python - Psycopg2 使用占位符插入表格

标签 python postgresql postgis psycopg2 psycopg

这可能是一个相当愚蠢的问题,但我在这里做错了什么?它创建了表格,但 INSERT INTO 不起作用,我想我对占位符做错了什么?

conn = psycopg2.connect("dbname=postgres user=postgres")
cur = conn.cursor()
escaped_name = "TOUR_2"
cur.execute('CREATE TABLE %s(id serial PRIMARY KEY, day date, elapsed_time varchar,    net_time varchar, length float, average_speed float, geometry GEOMETRY);' % escaped_name)

cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day ,time_length,  time_length_net, length_km, avg_speed,  myLine_ppy))

conn.commit()
cur.close()
conn.close()

INSERT INTO 调用不起作用,它给了我

cur.execute('INSERT INTO %s (day,elapsed_time, net_time, length, average_speed,  
geometry) VALUES (%s, %s, %s, %s, %s, %s)'% (escaped_name, day ,time_length,  
time_length_net, length_km, avg_speed,  myLine_ppy))
psycopg2.ProgrammingError: syntax error at or near ":"
LINE 1: ...h, average_speed, geometry) VALUES (2013/09/01 , 2:56:59, 02...

有人可以帮我解决这个问题吗?非常感谢!

最佳答案

您正在使用 Python 字符串格式,这是一个非常糟糕的主意 (TM)。想想 SQL 注入(inject)。正确的做法是使用绑定(bind)变量:

cur.execute('INSERT INTO %s (day, elapsed_time, net_time, length, average_speed, geometry) VALUES (%s, %s, %s, %s, %s, %s)', (escaped_name, day, time_length, time_length_net, length_km, avg_speed, myLine_ppy))

参数元组作为第二个参数提供给 execute()。此外,您不需要转义任何值,psycopg2 将为您进行转义。在这种特殊情况下,还建议不要在变量(escaped_name)中传递表名,而是将其嵌入到查询字符串中:psycopg2 不知道如何引用表名和列名,只有值.

参见 psycopg2 文档:

https://www.psycopg.org/docs/usage.html#passing-parameters-to-sql-queries

如果您想以编程方式生成 SQL 语句,通常的方法是对语句使用 Python 格式,对参数使用变量绑定(bind)。例如,如果您在 escaped_name 中有表名,您可以这样做:

query = "INSERT INTO %s (col1, ...) VALUES (%%s, ...)" % escaped_name
curs.execute(query, args_tuple)

显然,要在查询中使用占位符,您需要引用任何以第一种格式引入绑定(bind)参数的 %

请注意,这是安全的当且仅当 escaped_name 由您的代码生成,忽略任何外部输入(例如表基名称和计数器),但它是如果您使用用户提供的数据,则存在 SQL 注入(inject)的风险。

关于python - Psycopg2 使用占位符插入表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19235686/

相关文章:

python - 如何以编程方式在 django 1.7.6 中触发密码重置电子邮件?

python - Django:在模板中访问多对多(反向)

postgresql - 关于Postgres track_commit_timestamp (pg_xact_commit_timestamp)的问题

postgresql - Sequelize : where query string is in array of strings postgresql

php - 面向 PHP 开发人员的 PostgreSQL 和 MySQL 之间的差异

postgresql - 我的 postgresql 语法错误 (%) 符号

python - 已编译 Python 与 IronPython 的启动时间

python - 如何在 MacOS 上将 Python 2.x 升级到最新的 2.x 版本

postgresql - PostgreSQL 模式下的 h2 数据库不接受 PostgreSQL SQL 语法

postgis - 如何在 PostGIS 数据库中存储值网格,以便 GeoServer 可以绘制轮廓?