在Python的BigQuery中,空格会导致问题

在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

我有以下Python代码来检索BigQuery数据集。然后我在Jupyter上执行两个查询working\u querybad\u query。 唯一的区别是在后面的第3行添加了一个空格
…以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.