【问题标题】:Why does my interpolated SQL query have these extra quotation marks?为什么我的插值 SQL 查询有这些额外的引号?
【发布时间】:2021-09-18 14:20:03
【问题描述】:

我设置如下查询。我想用变量替换bucket_namefile_name

这个查询由psycopg2执行

query = '''copy table.test
                from 's3://%(bucket_name)s/%(file_name)s.txt'
                iam_role 'arn:aws:iam::123453215125:role/test'
                timeformat as 'auto'
                ACCEPTINVCHARS 
                delimiter '\t';'''

我得到存储桶名称和文件名

    bucket_name = get_bucket_name(event)
    file_name = get_file_name(event)

之后,我执行了查询,但它返回了错误

cur.execute(query, {'bucket_name':bucket_name,'file_name':file_name})
[ERROR] SyntaxError: syntax error at or near "expired" LINE 2: from 's3://'expired-test-bucket... ^ Traceback (most recent cal

好像bucket_name换成单引号'expired-test-bucket'

我想要的结果是expired-test-bucket

我该如何解决这个问题?

【问题讨论】:

  • 您可以尝试使用 python 的字符串 format() 和 {} 占位符作为存储桶名称和文件名。
  • 也许this thread 能帮上一点忙。

标签: python lambda psycopg2


【解决方案1】:

参数化查询中的参数像字符串插值一样工作,即使您use pyformat binding style that happens to look like old-school %-based string interpolation。之所以有引号,是因为数据库引擎希望您使用占位符来表示整个参数,并将引号(以及可能的各种形式的转义)放入最终查询文本中设计特别是为了防止将用户数据直接插入到查询中而导致的安全漏洞。

如果您需要使用用户数据来构建在查询中使用的值,那么请按照单独的步骤执行此操作:首先,使用 Python 字符串格式化来创建原始基础值,然后使用 SQL 引擎的确保将该值放入查询中的安全功能。

所以,类似:

bucket_name = get_bucket_name(event)
file_name = get_file_name(event)
url = f's3://{bucket_name}/{file_name}.txt'

query = '''copy table.test
           from %s
           iam_role 'arn:aws:iam::123453215125:role/test'
           timeformat as 'auto'
           ACCEPTINVCHARS 
           delimiter '\t';'''

cur.execute(query, (url,))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 2014-09-19
    • 1970-01-01
    • 2015-07-02
    • 2011-06-17
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多