我不确定为什么不适合您使用 wildcard table 搜索您的数据库,就像您提到的帖子中一样。因为我已经运行了这个示例查询来搜索一个公共数据集,它工作得很好。
SELECT *
FROM `bigquery-public-data.baseball.*` b
WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r'Cubs')
我想这是因为其中一个限制是通配符表功能不支持视图。
你有很多吗?
在这种情况下,您可以仅将通配符用于您的表,并使用 _TABLE_SUFFIX 或不太通用的通配符(这取决于您的视图名称)过滤掉视图。
一般来说,对于通配符表,使用 _TABLE_SUFFIX 可以大大减少扫描的字节数,从而降低运行查询的成本。因此,如果您怀疑某些表包含的字符串比其他表多,也可以使用它。
对于视图(或整个数据集),您可以:
• 通过使用libraries 之一和Python 中的multiprocessing 等多处理模块调用BigQuery API 进行迭代。
• 通过从 bash 脚本调用 REST API 进行迭代。
• 使用 bash 脚本中的 bq command 进行迭代。
如果您在编程部分遇到问题,请发布一个新问题并在此处添加链接。
编辑:
这里有两个示例(bash 和 python)。我尝试了这两种方法,它们都有效,但当然欢迎任何有助于改进的 cmets。
Python:
- 安装包
pip install --upgrade google-cloud-bigquery
pip install multiprocess
- 创建
filename.py。更改YOUR_PROJECT_ID 和YOUR_DATASET。
from google.cloud import bigquery
import multiprocessing
def search(dataset_id):
"""
Lists and filters your dataset to keep only views
"""
client = bigquery.Client()
tables = client.list_tables(dataset_id)
views = []
for table in tables:
if table.table_type == 'VIEW':
views.append(table.table_id)
return views
def query(dataset_id, view):
"""
Searches for the string in your views and prints the first one it finds.
You can change or remove 'LIMIT 1' if needed.
"""
client = bigquery.Client()
query_job = client.query(
"""
SELECT *
FROM {}.{} b
WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r"true")
LIMIT 1
""".format(dataset_id, view)
)
results = query_job.result() # Waits for job to complete.
for row in results:
print(row)
if __name__ == '__main__':
# TODO: Set dataset_id to the ID of the dataset that contains the tables you are listing.
dataset_id = 'YOUR_PROJECT_ID.YOUR_DATASET'
views = search(dataset_id)
processes = []
for i in views:
p = multiprocessing.Process(target=query, args=(dataset_id, i))
p.start()
processes.append(p)
for process in processes:
process.join()
运行python filename.py
重击:
- 安装jq(json解析器)并测试
sudo apt-get install jq
测试
echo '{ "name":"John", "age":31, "city":"New York" }' | jq .
输出:
{
"name": "John",
"age": 31,
"city": "New York"
}
Reference
- 创建
filename.sh。更改YOUR_PROJECT_ID 和YOUR_DATASET。
#!/bin/bash
FILES="bq ls --format prettyjson YOUR_DATASET"
RESULTS=$(eval $FILES)
DETAILS=$(echo "${RESULTS}" | jq -c '.[]')
for d in $DETAILS
do
ID=$(echo $d | jq -r .tableReference.tableId)
table_type=$(echo $d | jq -r '.type')
if [[ $table_type == "VIEW" ]]
then
bq query --use_legacy_sql=false \
'SELECT *
FROM
`YOUR_PROJECT_ID`.YOUR_DATASET.'$ID' b
WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r"true")
LIMIT 1'
fi
done
运行bash filename.sh