使用psycopg2将列名作为参数传递给PostgreSQL

nod*_*ase 16 python sql postgresql parameters psycopg2

我正在尝试使用添加列到表 psycopg2

row1下面是要添加到表中的列名列表.我可以手动完成,但当我尝试以编程方式执行此操作时,我收到错误.

for c in row1:
    cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text", (c,))
Run Code Online (Sandbox Code Playgroud)

错误是:

    cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text", (c,))
psycopg2.ProgrammingError: syntax error at or near "'HOUSEID'"
LINE 1: ALTER TABLE HHV2PUB ADD COLUMN 'HOUSEID' text
Run Code Online (Sandbox Code Playgroud)

我的猜测是它与单引号有关 ''

Clo*_*eto 20

从Psycopg 2.7开始,有一个安全sql模块:

from psycopg2 import sql

query = sql.SQL("alter table t add column {} text")

row1 = ('col1', 'col2')
for c in row1:
    cursor.execute(query.format(sql.Identifier(c)))
Run Code Online (Sandbox Code Playgroud)

2.6及更早版本:

使用 psycopg2.extensions.AsIs

适配器符合ISQLQuote协议,该协议对于其字符串表示已作为SQL表示有效的对象非常有用.

import psycopg2
from psycopg2.extensions import AsIs

conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn")
cursor = conn.cursor()

query = "alter table t add column %s text"

row1 = ('col1', 'col2')
for c in row1:
    cursor.execute(query, (AsIs(c),))
conn.commit()
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这并不比使用对象名称的直接插值更安全. (3认同)

Mar*_*ers 6

您不能将SQL参数用于SQL对象名称.SQL参数明确地引用值,以便它们不能被解释为这样; 这是主要的原因,使用SQL的参数之一,否则.

你必须在这里使用字符串插值.请务必小心不要c在此处使用用户输入:

for c in row1:
    cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text" % c)
Run Code Online (Sandbox Code Playgroud)

Psycopg2确实为您提供了一种将参数标记为"已经转义"的方法psycopg2.extensions.AsIs(),但目的是将其用于已转义的数据.

更好的想法是使用psycopg2.sql扩展来管理正确的标识符转义:

from psycopg2 import sql

for c in row1:
    cur.execute(
        sql.SQL("ALTER TABLE HHV2PUB ADD COLUMN {} text").format(
            sql.Identifier(c)))
Run Code Online (Sandbox Code Playgroud)