红移查询中的转义引号

2024-06-14 16:58:25 发布

您现在位置:Python中文网/ 问答频道 /正文


为了提高可读性,我正试图将代码重构为PEP8标准,但在SQL查询中,我很难摆脱引号。 我有两个问题。第一个是简单的SQL查询。第二个是Redshift UNLOAD命令。

query = '''SELECT * FROM redshift_table
           LEFT JOIN
           (SELECT DISTINCT * FROM redshift_view) v
           ON redshift_table.account_number = v.card_no
           WHERE timestamp < date_trunc('day', CURRENT_DATE)
           AND timestamp >=  (CURRENT_DATE - INTERVAL '1 days')'''

unload = '''UNLOAD ('%s') to '%s'
            credentials 'aws_access_key_id=%s;aws_secret_access_key=%s'
            delimiter as '%s'parallel off ALLOWOVERWRITE''' % (query, s3_path, access_key, aws_secret, file_delimiter)

因为sql查询嵌入在UNLOAD命令中,所以我只能通过在引号前面加上3个反斜杠来进行转义:“day”变为//“day///”。
这不太理想,我想知道有没有办法。

任何帮助都非常感谢。谢谢您。


Tags: keyfrom命令awsredshiftsqlaccesstable
2条回答

由于只需要在unload命令中的引号前插入反斜杠,因此使用escape函数可以工作。这是一个例子。

def escape_quote(value):
  return value.replace("'", "\\'")

query = '''SELECT * FROM redshift_table
           LEFT JOIN
           (SELECT DISTINCT * FROM redshift_view) v
           ON redshift_table.account_number = v.card_no
           WHERE timestamp < date_trunc('day', CURRENT_DATE)
           AND timestamp >=  (CURRENT_DATE - INTERVAL '1 days')'''

unload = '''UNLOAD ('%s') to '%s'
            credentials 'aws_access_key_id=%s;aws_secret_access_key=%s'
            delimiter as '%s'parallel off ALLOWOVERWRITE''' % (escape_quote(query), s3_path, access_key, aws_secret, file_delimiter)

Masashi的答案并不总是有效,例如,如果查询中已经有转义字符串(例如在正则表达式中)。

为了获得更可靠的解决方案,您可以利用美元报价。Redshift文档指向“this page”部分中的“美元引用字符串常量”。您可以使用美元符号来引用查询,而不是手动转义引号,如下所示:

unload = """UNLOAD ($$ %s $$) ...as""" % (query, ...)

当然,如果在查询中的任何地方使用$$,这也会中断。如果您想真正安全,请在美元符号内使用随机标记:

import uuid

# Leading underscore is necessary since this needs to be a valid
# identifier, i.e. can only start with a letter or underscore.
quote_tag = '_' + uuid.uuid4().hex

unload = 'UNLOAD ($%s$ %s $%s$) ...'.format(quote_tag, query, quote_tag, ...)

相关问题 更多 >