如何在bigquerysql中安全地参数化表/列名?

aydmsdu9  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(438)

我使用python的bigquery客户机在bigquery中创建并保持一些表的最新状态,这些表包含特定firebase事件的每日计数,这些事件与来自其他来源的数据(有时按国家等分组)相关联。要使它们保持最新,需要删除和替换过去几天的数据,因为firebase事件的日表在创建之后可以更改(请参阅此处和此处)。我以这种方式使它们保持最新,以避免查询整个数据集,这在财务/计算上非常昂贵。
这个删除和替换过程需要对许多表重复,因此我需要重用存储在文本文件中的一些查询。例如,从特定日期开始删除表中的所有内容( delete from x where event_date >= y ). 但是由于bigquery不允许表名的参数化(参见这里),因此我必须为每个需要执行此操作的表复制这些查询文本文件。如果我想运行测试,我还必须复制前面提到的对测试表的查询。
我基本上需要 psycopg2.sql 以便我可以安全地参数化表和列名,同时避免使用sqli。实际上,我试图通过调用 as_string() 方法并使用结果查询bigquery。但是产生的语法不匹配,我需要启动一个postgres连接来完成( as_string() 需要游标/连接对象)。我也试过类似的方法 sqlalchemy.text 无济于事。所以我总结说,我必须自己实现一些参数化表名的方法,或者使用python客户机库实现一些变通方法。我该如何以一种不会导致sqli的安全方式来做这件事呢?无法详细说明,但不幸的是,我无法将表存储在postgres或任何其他db中。

06odsfpq

06odsfpq1#

正如评论中所讨论的,在您的情况下避免使用sqli的最佳选择是确保服务器的安全性。
无论如何,如果您需要/想要在构建查询之前解析输入参数,我建议您使用 REGEX 以检查输入字符串。在python中,可以使用 re 图书馆。
由于我不知道您的代码是如何工作的,数据集/表是如何组织的,也不知道您计划如何检查字符串是否是有效的源代码,因此我创建了下面的基本示例,演示如何使用此库检查字符串

import re

tests = ["your-dataset.your-table","(SELECT * FROM <another table>)", "dataset-09123.my-table-21112019"]

# Supposing that the input pattern is <dataset>.<table>

regex = re.compile("[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+")

for t in tests:
    if(regex.fullmatch(t)):
        print("This source is ok")
    else:
        print("This source is not ok")

在本例中,只有与configuration dataset.table匹配的字符串(其中dataset和table必须仅包含字母数字字符和破折号)才会被视为有效。
运行代码时,列表的第一个和第三个元素将被视为有效,而第二个元素(可能会改变整个查询)将被视为无效。

相关问题