首页 > 解决方案 > 正确使用 Psycopg2 SQL 模块

问题描述

由于莫里斯·迈耶(Maurice Meyer)让我意识到的语法错误而编辑了问题

我需要保护应用程序免受 SQL 注入,因此使用Psycopg2中的sql模块。这会生成一个工作查询:

conn = get_db()
cur = conn.cursor()
with open(fp, 'r') as f:
    query = sql.SQL("COPY parts ({fields}) FROM STDIN WITH (FORMAT CSV, DELIMITER ';', ENCODING UTF8)").format(
        fields = sql.SQL(',').join(sql.Identifier(col) for col in cols))
    cur.copy_expert(query, f)

但是我想知道这是否是正确的解决方案。由于生成的查询是:

print(query.as_string(conn))
>>> COPY parts ("asin","name","t_id","supp_pid","acq_price","deposit","ean","m_pid") FROM STDIN WITH (FORMAT CSV, DELIMITER ';', ENCODING UTF8)

但是根据Postgresql 文档,标识符应该不加引号。为什么它仍然有效?

标签: pythonsql-injectionpsycopg2composable

解决方案


你有一个错字:

sql.SQL("xxx".format(...))

代替:

sql.SQL("xxx").format(...)
             ^ this (

所以:

query = sql.SQL("COPY parts ({fields}) FROM STDIN WITH (FORMAT CSV, DELIMITER ';', ENCODING UTF8)").format(
        fields = sql.SQL(',').join(sql.Identifier(col) for col in cols))

推荐阅读