如何从另一个 bigquery 响应将值插入 mysql 表

Posted

技术标签:

【中文标题】如何从另一个 bigquery 响应将值插入 mysql 表【英文标题】:how to insert values into mysql table from another bigquery response 【发布时间】:2016-06-14 16:04:48 【问题描述】:

我的 Python 程序连接到 BigQuery 并获取我想要插入 mysql 表的数据。它成功地从 BigQuery 获取结果。它也成功连接到 MySQL DB,但没有插入数据。我看到它在抱怨row[1]

将 BigQuery 响应中的值插入 MySQL 表列的正确方法是什么?

query_data = mybigquery

query_response = query_request.query(projectId='myprojectid',body=query_data).execute()

for row in query_response['rows']:
  cursor.execute ("INSERT INTO database.table VALUES ('row[0]','row[1]','row[2]','row[3]','row[4]');")

另外,我尝试使用

cursor.execute ("INSERT INTO database.table VALUES (%s,%s,%s,%s,%s);")

cursor.execute ("INSERT INTO database.table VALUES (row[0],row[1],row[2],row[3],row[4]);")

但是在mysql表中插入值时失败了

【问题讨论】:

【参考方案1】:

字符串字面量

关于原始问题,问题在于引用您的变量。这会导致execute 函数将它们视为字符串文字,而不是从中获取值。

正如@Herman 所建议的那样,要使用我认为您想要的值正确执行 SQL 语句,您需要更像这样的东西:

query_data = mybigquery
statement = 'INSERT INTO database.table VALUE (%s, %s, %s);'

response = query_request.query(projectId='myprojectid', body=query_data).execute()
rows = response['rows']
for row in rows:
  values = (row[0], row[1], row[2])
  cursor.execute(statement, values)


BigQuery 查询 JSON

但请记住,上面的代码不会开箱即用,因为上面代码中的 row 不符合从 BigQuery Job: query API 收到的响应。

在此 API 中,rowsrow 对象的数组。每个row 对象都有一个属性f,它是一个字段数组。最后,每个field 都有一个属性v,这是该字段的值。

要连续获取第二个字段的值,您应该使用row['f'][1]['v']。由于cursor.execute() 方法的params 参数需要tuplelist,因此您可以使用列表推导式获取字段值列表,如下所示:

for row in rows:
  values = [field['v'] for field in row['f]]


在插入前清理值

您在正确读取字段值后得到的TypeError 可能会出现问题,因为executestr 无法正确地将值转换为字符串。 BigQuery 和 MySQL 之间的显着区别之一是 BigQuery 中的一个值可以是一个 record,它有多个自己的值。为确保正确插入这些值,您必须在插入它们之前自己清理这些值。如果该值为listdict,则如果不以某种方式(如str 方法)进行序列化,则无法将其存储在MySQL 中。


示例

def sanitize(value):
  if type(value) is list:
    return str(value)
  if type(value) is dict:
    return str(value)
  # this may be required for other types
  return value

data = mybigquery
statement = 'INSERT INTO database.table VALUE (%s, %s, %s);'

response = request.query(projectId='projid', body=data).execute()
for row in response['rows']:
  values = [sanitize(field['v']) for field in row['f']]
  cursor.execute(statement, values)

这是非常基本的卫生设施。您应该真正验证所有字段值并确保它们将正确转换为 MySQL 类型,而不是简单地插入值数组。

【讨论】:

【参考方案2】:

错误信息是什么?它应该是这样的:

cursor.execute( "INSERT INTO database.table VALUES (%s, %s, %s, %s, %s)", row[0:5])

【讨论】:

得到这个错误 [root@myserver ~]# python myprogram.py Traceback (最近一次调用最后):文件“myprogram.py”,第 25 行,在 cursor.execute("INSERT INTO database.table VALUES (%s, %s, %s, %s, %s)", row[0:5]) TypeError: unhashable type [root@myserver ~]# 我明白了。看起来您需要 str 所有的值,因为驱动程序不会为您执行此操作。 cursor.execute("INSERT INTO database.table VALUES (%s, %s, %s, %s, %s)", [str(r) for r in row[0:5]]) 仍然遇到同样的错误...基本上,当我使用 print('\t'.join(field['v'] for field in row['f'])) 打印时值很好... 输出 15658 53.35023630093262 221.0 237.0 436.0 但是当我尝试使用 connection = MySQLdb.connect (host = "localhost", user = "root", passwd = "secretpwd", db = "database") cursor = connection.cursor () for row in query_response['rows']: cursor.execute("INSERT INTO database.table VALUES (%s, %s, %s, %s, %s)", [str(r) for r in row[0:5]]) TypeError: unhashable type

以上是关于如何从另一个 bigquery 响应将值插入 mysql 表的主要内容,如果未能解决你的问题,请参考以下文章

如何通过ajax fetch api响应将从laravel控制器接收到的数据发送到另一个页面

使用表单的响应将数据集属性保存在 JSON 文件中 (Vue.js)

如何使用 DML 语法在 BigQuery 中插入带有 RECORD 字段的记录?

如何使用 dbapi 将值列表插入 BigQuery 表

如何在 Bigquery 中插入一个接收 json 字符串值的字段?

来自 Dataflow 的 BigQuery 流式插入 - 没有结果