我必须为postgresql构造一个动态更新查询。它是动态的,因为事先我必须确定要更新哪些列。
给定一个示例表:
create table foo (id int, a int, b int, c int)
然后,我将以编程方式构造"set"子句
_set = {}
_set['a'] = 10
_set['c'] = NULL
之后我必须构建更新查询。我在这里卡住了。我必须构造这个sql更新命令:
update foo set a = 10, b = NULL where id = 1
如何使用psycopg2参数化命令来实现这一点?(即,如果dict不为空,则循环通过dict并构建set子句)?
- 更新**
当我睡觉的时候,我自己找到了解决办法。它是动态的,正是我想要的:-)
create table foo (id integer, a integer, b integer, c varchar)
updates = {}
updates['a'] = 10
updates['b'] = None
updates['c'] = 'blah blah blah'
sql = "upgrade foo set %s where id = %s" % (', '.join("%s = %%s" % u for u in updates.keys()), 10)
params = updates.values()
print cur.mogrify(sql, params)
cur.execute(sql, params)
结果就是我所需要的内容和方式(特别是可空列和可引用列):
"upgrade foo set a = 10, c = 'blah blah blah', b = NULL where id = 10"
5条答案
按热度按时间t9aqgxwy1#
实际上有一种稍微干净一点的方法,使用the alternative column-list syntax:
pbossiut2#
使用psycopg2.sql- SQL字符串合成模块
该模块包含的对象和函数可用于以方便和安全的方式动态生成SQL。
在关闭连接之前运行
print(sql_query.as_string(conn))
将显示以下输出:5kgi1eie3#
不需要动态SQL,假设
a
不可空,b
可空。如果要同时更新
a
和b
:输出:
如果不想更新任何内容:
输出:
dgiusagp4#
一个不带python格式的选项,使用psycopg2的
AsIs
函数作为列名(尽管这并不妨碍在列名上进行SQL注入)。sulc1iza5#
这是我在一个泛型
DatabaseHandler
类中的解决方案,当使用pd.DataFrame
作为源代码时,它提供了很大的灵活性。示例用法:
但是请注意,由于它生成where子句的方式,这对于SQL注入是不安全的。