这可能是一个相当愚蠢的问题,但我在这里做错了什么?它创建了表,但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...
有人可以帮我这个吗?非常感谢!
答案 0 :(得分:27)
您正在使用Python字符串格式,这是一个非常糟糕的想法(TM)。想想SQL注入。正确的方法是使用绑定变量:
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文档:
http://www.psycopg.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
如果要以编程方式生成SQL语句,通常的方法是使用Python格式化语句和参数的变量绑定。例如,如果您在escaped_name
中有表名,则可以执行以下操作:
query = "INSERT INTO %s (col1, ...) VALUES (%%s, ...)" % escaped_name
curs.execute(query, args_tuple)
显然,要在查询中使用占位符,您需要引用以第一种格式引入绑定参数的任何%
。
请注意,这是安全的当且仅当您的代码生成 escaped_name
时忽略任何外部输入(例如表基名和计数器)但它有风险如果您使用用户提供的数据,则使用SQL注入。
答案 1 :(得分:1)
从psycopg2 v2.7
开始,有一种支持的方式:[{3}}。
答案 2 :(得分:1)
为了扩展@Matt 的回答,占位符不适用于表名等标识符,因为该名称将被引用为字符串值并导致语法无效。
如果你想动态生成这样的查询,你可以使用referred to pyscopg2.sql
module:
dispatch