我有一个清单:
[u'ABC', u'DEF', u'GHI']
Run Code Online (Sandbox Code Playgroud)
我必须将它插入到postgresql数组中:( ALTER TABLE "aTable" ADD COLUMN "Test" text[];
)
将数据添加到postgresql的语法是:
update "aTable" SET "Test" = '{"ABC", "DEF", "GHI"}'
Run Code Online (Sandbox Code Playgroud)
如何将列表转换为正确的格式?
exh*_*uma 12
请注意,psycopg2
您不需要对数组执行任何字符串处理.这被认为是不好的做法,因为它容易出错,并且 - 在最坏的情况下 - 会导致开放注入攻击!您应该始终使用绑定参数.在下面的代码中,我将创建一个新表,其中只有一列具有类型TEXT[]
(如原始问题中所示).然后我将添加一个新行,并更新所有行.所以你会看到一个INSERT
和一个UPDATE
操作(虽然两者几乎完全相同).
如果只使用一个值更新,则有一个Python问题:cur.execute
期望SQL语句作为第一个参数,并且包含要作为第二个参数绑定的参数的iterable.下面将不工作:
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values))
Run Code Online (Sandbox Code Playgroud)
原因是(new_values)
python看到new_values
(在这种情况下,parens被丢弃,它们不被视为元组).这将导致您提供3个值('a'
,'b'
和'c'
)作为要绑定的值的错误,但%s
查询中只有一个占位符().相反,您必须按如下方式指定它(注意最后添加的逗号):
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values,))
Run Code Online (Sandbox Code Playgroud)
这将使Python (new_values,)
看作具有一个元素的元组(这是一个可迭代的),它与查询占位符相匹配.有关尾随逗号的更详细说明,请参阅有关元组的官方文档.
或者,你也可以写[new_values]
而不是(new_values,)
,但是 - 在我看来 - (new_values,)
因为元组是不可变的而更清晰,而列表是可变的.
这是我测试的表格:
CREATE TABLE foo (
values TEXT[]
);
Run Code Online (Sandbox Code Playgroud)
这里是插入和更新值的Python代码:
from psycopg2 import connect
conn = connect('dbname=exhuma')
cur = conn.cursor()
cur.execute('INSERT INTO foo VALUES (%s)', (['a', 'b'], ))
print('>>> Before update')
cur.execute('SELECT * FROM foo')
for row in cur:
print(type(row[0]), repr(row[0]))
print('>>> After update')
cur.execute('UPDATE foo SET example_values = %s',
(['new', 'updated', 'values'],))
cur.execute('SELECT * FROM foo')
for row in cur:
print(type(row[0]), repr(row[0]))
cur.close()
conn.commit()
conn.close()
Run Code Online (Sandbox Code Playgroud)
在每次执行时,代码将插入具有相同数组值的新行,然后执行update without WHERE
子句,以便更新所有值.经过几次执行后,我给出了以下输出:
>>> Before update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['a', 'b']")
>>> After update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
Run Code Online (Sandbox Code Playgroud)
您只需将该列表作为参数传递给execute
.你不需要做任何特别的事情.Psycopg将Python列表转换为合适的PostgreSQL数组文字.
import psycopg2 as dbapi
conn = dbapi.connect(dsn='')
c = conn.cursor()
x = [u'ABC', u'DEF', u'GHI']
c.execute('update "aTable" SET "Test" = %s', [x])
Run Code Online (Sandbox Code Playgroud)
list = [u'ABC', u'DEF', u'GHI']
list = str(map(str, list))
list = list.replace('[', '{').replace(']', '}').replace('\'', '\"')
query = '''update "aTable" SET "Test" = '%s\'''' %(list)
print query
Run Code Online (Sandbox Code Playgroud)
将导致,
update "aTable" SET "Test" = '{"ABC", "DEF", "GHI"}'
Run Code Online (Sandbox Code Playgroud)