我试图将我的代码重构为PEP8标准以便于阅读,但我正在努力逃避SQL查询中的引号。
我有2个查询。第一个是简单的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 ///'。
这不太理想,我想知道是否有办法绕过它。
非常感谢任何帮助。谢谢。
答案 0 :(得分:2)
例如,如果查询中已经存在转义的字符串(例如,在正则表达式中),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, ...)
答案 1 :(得分:0)
由于您只需要在unload命令中的引号之前插入反斜杠,因此使用转义函数可以正常工作。这是一个例子。
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)