加载源自csv文件的大量数据的可行方法是什么?

时间:2017-11-07 22:40:41

标签: python google-bigquery

背景

最终我正在尝试将大量数据加载到GBQ中。许多日期的大多数秒都有记录。

我想为每天的数据提供一个表格,以便我可以使用以下语法查询集合:     _TABLE_SUFFIX BETWEEN'20170403'和'20170408'......

某些列将嵌套,列集当前源自大量30-150mb的大量csv文件。

方法

我处理文件的方法是:

1)创建具有正确架构的表

2)为每个表填写每秒的记录,为循环数据和运行UPDATE查询做准备

3)循环浏览csv文件并加载数据

所有这些都是由python的GBQ客户端库驱动的。

步骤(2)可能看起来很奇怪,但我认为为了简化加载需要它,因为我能够保证UPDATE DML在所有情况下都能正常工作。

我确实认识到(3)在给出(2)的问题的情况下几乎没有机会工作,但是我在稍微小的范围内进行了类似的操作,这使我相信我的方法可能不会完全没有希望规模。

我还想知道这是否是加载此类数据的最合适的方法,但GBQ文档中提供的一些选项似乎对于一次性数据加载可能过度,即我不会我想学习apache beam,除非我知道我必须考虑到我的主要关注点是分析数据集。但是,如果我知道这是完成这样一个负载的唯一方法,那我就不会学习像apache beam这样的东西,因为它可以在将来派上用场。

我遇到的问题

为了运行(2)我有三个嵌套for循环,循环每小时,分钟秒并构造一个长字符串进入INSERT查询:

(TIMESTAMP '{timestamp}', TIMESTAMP '2017-04-03 00:00:00', ... + ~86k times for each day)

GBQ不允许你运行这么长的查询有一个限制,从内存它的250k字符(可能是错误的)。因此,在每次迭代时测试查询的长度,如果它超过略低于250k字符的数字,则执行插入查询。

虽然这在我运行时涉及更多列的类似操作类型,但是当GQB返回时,该过程终止:

"google.cloud.exceptions.BadRequest: 400 Resources exceeded during query execution: Not enough resources for query planning - too many subqueries or query is too complex.."

当我减小字符串的大小并运行较小的查询时,此错误的返回频率较低,但不会一起消失。不幸的是,在这种缩小的查询大小下,脚本将花费太长时间来完成以作为步骤(2)的可行选项。它需要> 600秒,整个数据集将需要超过20天才能运行。

我原本以为将查询模式更改为'BATCH'可能会克服这个问题,但有人向我指出这无济于事,我还不清楚为什么,但很乐意接受某人的话。因此,我进一步详述了这个问题,因为我的方法似乎可能是错误的。

这就是我所看到的相关代码块:

from google.cloud import bigquery
from google.cloud.bigquery import Client
... ...
bqc = Client()
dataset = bqc.dataset('test_dataset')
job = bqc.run_async_query(str(uuid.uuid4()), sql)
job.use_legacy_sql = False
job.begin()

加载此数据集的最佳方法是什么?有没有办法让我目前的方法工作?

查询

INSERT INTO `project.test_dataset.table_20170403` (timestamp) VALUES (TIMESTAMP '2017-04-03 00:00:00'), ...   for ~7000 distinct values

更新

自从我上次下载以来,似乎GBQ客户端库已经进行了无关紧要的升级Client.run_asyn_query()似乎已被Client.query()取代。我将尝试使用新代码并报告回来。

0 个答案:

没有答案