在Python的BigQuery中,空格会导致问题
我有以下Python代码来检索BigQuery数据集。然后我在Jupyter上执行两个查询working\u query和bad\u query。 唯一的区别是在后面的第3行添加了一个空格在Python的BigQuery中,空格会导致问题,python,sql,caching,google-bigquery,whitespace,Python,Sql,Caching,Google Bigquery,Whitespace,我有以下Python代码来检索BigQuery数据集。然后我在Jupyter上执行两个查询working\u query和bad\u query。 唯一的区别是在后面的第3行添加了一个空格 …以q的形式发布问题,这会导致错误查询失败,并显示消息 查询超出了计费字节的限制:1000000000。需要24460132352或更高版本。 我知道已经启用了成本控制,但不知道这是怎么回事。 我将来怎样才能避免这样的陷阱?有人能解释一下这个问题吗 from google.cloud import bigqu
…以q的形式发布问题
,这会导致错误查询失败,并显示消息
查询超出了计费字节的限制:1000000000。需要24460132352或更高版本。
我知道已经启用了成本控制,但不知道这是怎么回事。
我将来怎样才能避免这样的陷阱?有人能解释一下这个问题吗
from google.cloud import bigquery
client = bigquery.Client()
dataset_ref = client.dataset("stackoverflow", project="bigquery-public-data")
dataset = client.get_dataset(dataset_ref)
safe_config = bigquery.QueryJobConfig(maximum_bytes_billed=10**10)
answers_query_job = client.query(working_query, job_config=safe_config)
answers_query_job.to_dataframe()
更新:
这是一个缓存问题,因为在激活成本控制之前运行了正在运行的查询。这样,即使启用了成本控制,它也可以从缓存中检索数据。
查询必须完全相同才能共享缓存,因此即使添加了空格也可以防止出现这种情况。您可能启用了成本控制: 此错误意味着您的查询将要扫描的字节数超过“计费的最大字节数”中设置的限制 你能可靠地重现这个错误吗?查询中的空白看起来与BigQueryrols中的成本控制无关。。也许只是巧合,要么是数据更大,要么是引入了成本控制 编辑:Alexandre的回答是正确的——“好的查询”成功了,因为它从缓存中获取结果。仅使用重试(注意:在上面的注释线程中使用\u查询\u缓存,而不是使用QueryCache) 对于好的查询,得到了相同的错误。此外,您还可以在结果作业中检查cache_hit,以查看是否从缓存中获取响应。只要查询成功,它就等于true:
print("Cache hit: ")
print(answers_query_job.cache_hit)
我已经使用您的两个查询执行了一些测试,它们是以相同的方式执行的 首先,我必须指出query()方法接收一个字符串,并使用job\u config配置作业。此外,文档中没有提到任何与查询字符串中的额外空格有关的问题 此外,如果您导航到BigQuery UI,一次复制并粘贴一个查询并执行它,您将在作业信息下看到,两个查询将处理大约23Gb的数据,相同数量的数据将是计费的字节。因此,如果设置
bigquery.QueryJobConfig(最大字节数\u账单=23000000000)
并省略to\u dataframe()
方法,则上述两个查询都将完美运行
更新:
根据,默认情况下,您将use\u query\u cache
设置为true,这意味着如果运行相同的查询,它将从以前的查询中检索结果。因此,不会处理任何字节。如果以前运行查询时未设置最大字节数\u账单
。然后以最大数量运行同一查询,即使该查询的处理量大于您现在设置的处理量,该查询仍将运行
在您的例子中,我使用了来自AI平台的Python3笔记本和Shell中的.py文件来运行以下代码
第一个代码
from google.cloud import bigquery
import pandas
client = bigquery.Client()
dataset_ref = client.dataset("stackoverflow", project="bigquery-public-data")
dataset = client.get_dataset(dataset_ref)
job_config = bigquery.QueryJobConfig(maximum_bytes_billed=10**10)
job_config.use_query_cache = False
working_query = """
SELECT a.id, a.body, a.owner_user_id
FROM `bigquery-public-data.stackoverflow.posts_answers` AS a
INNER JOIN `bigquery-public-data.stackoverflow.posts_questions` AS q
ON q.id = a.parent_id
WHERE q.tags LIKE '%bigquery%'
"""
answers_query_job = client.query(working_query, job_config)
answers_query_job.to_dataframe()
第二个代码
from google.cloud import bigquery
import pandas
client = bigquery.Client()
dataset_ref = client.dataset("stackoverflow", project="bigquery-public-data")
dataset = client.get_dataset(dataset_ref)
job_config = bigquery.QueryJobConfig(maximum_bytes_billed=10**10)
job_config.use_query_cache = False
bad_query = """
SELECT a.id, a.body, a.owner_user_id
FROM `bigquery-public-data.stackoverflow.posts_answers` AS a
INNER JOIN `bigquery-public-data.stackoverflow.posts_questions` AS q
ON q.id = a.parent_id
WHERE q.tags LIKE '%bigquery%'
"""
answers_query_job = client.query(working_query, job_config)
answers_query_job.to_dataframe()
上述代码均无效。它们导致了以下错误:
Query exceeded limit for bytes billed: 10000000000. 24460132352 or higher required.
另一方面,如果设置了
job\u config=bigquery.QueryJobConfig(最大字节数\u账单=2500000000)
。这两个查询都正常运行。我希望启用成本控制,但不明白为什么空白或任何空白会触发此行为。@glykocalyx,查询将处理23Gb的数据,并且计费将超过10**10,这是最大值。因此,所有查询都不会运行。我用shell复制了它,没有一个使用这个最大集。另一方面,如果将其设置为bigquery.QueryJobConfig(最大字节数\u账单=23000000000)
并将注释设置为\u dataframe()
,则两者都会运行。它们处理相同数量的数据,你可以在BigQueryUI中的作业详细信息下看到这一点。“工作查询”将从kaggle笔记本运行。问题是,为什么?@glykocalyx,您可能启用了缓存结果。因此,您只运行了一次查询,没有设置最大限制,然后当您再次运行时,将使用缓存的结果。查询字符串中的额外空间与此无关。我使用shell和AI平台内的笔记本复制了您的案例,如果您设置了正确的总字节数\u账单
,两个查询都能正常工作。我更新了我的答案,更详细地解释了我的复制。很可能是kaggle笔记本,我会朝这个方向看。谢谢你的回答,我知道成本控制已经启用,问题是为什么空白会触发这种行为?这是我的笔记本的链接,是的,它是可复制的。这确实是Alexandre在回复中提到的查询缓存问题-我刚刚用use\u query\u cache=False重试了你的笔记本,我看到同样的错误更新了回复,不幸的是,我无法对上面的评论线程发表评论。Alexandre Moraes走在正确的道路上,只是应该使用use\u query\u cache=True而不是UseQueryCache。请参阅此处的文档:是。处理查询不需要任何成本,因为它只是从缓存加载数据。因此,它不受成本控制的影响,不管你在那里设置什么。因为它是免费的。由于成本控制,错误查询总是失败。为了实验起见,如果您可以在关闭成本控制的情况下运行bad_查询,那么它也会有缓存值,并且如果重试,同样会开始成功。引用文档:“要从缓存中检索数据,重复的查询文本必须与原始查询完全相同。”。因此,即使添加空间也会导致缓存失效。你完全正确,只是做了实验,结果正如你所说的那样。非常感谢。
from google.cloud import bigquery
import pandas
client = bigquery.Client()
dataset_ref = client.dataset("stackoverflow", project="bigquery-public-data")
dataset = client.get_dataset(dataset_ref)
job_config = bigquery.QueryJobConfig(maximum_bytes_billed=10**10)
job_config.use_query_cache = False
working_query = """
SELECT a.id, a.body, a.owner_user_id
FROM `bigquery-public-data.stackoverflow.posts_answers` AS a
INNER JOIN `bigquery-public-data.stackoverflow.posts_questions` AS q
ON q.id = a.parent_id
WHERE q.tags LIKE '%bigquery%'
"""
answers_query_job = client.query(working_query, job_config)
answers_query_job.to_dataframe()
from google.cloud import bigquery
import pandas
client = bigquery.Client()
dataset_ref = client.dataset("stackoverflow", project="bigquery-public-data")
dataset = client.get_dataset(dataset_ref)
job_config = bigquery.QueryJobConfig(maximum_bytes_billed=10**10)
job_config.use_query_cache = False
bad_query = """
SELECT a.id, a.body, a.owner_user_id
FROM `bigquery-public-data.stackoverflow.posts_answers` AS a
INNER JOIN `bigquery-public-data.stackoverflow.posts_questions` AS q
ON q.id = a.parent_id
WHERE q.tags LIKE '%bigquery%'
"""
answers_query_job = client.query(working_query, job_config)
answers_query_job.to_dataframe()
Query exceeded limit for bytes billed: 10000000000. 24460132352 or higher required.