Python列表到PostgreSQL数组

sar*_*mba 7 python postgresql

我有一个清单:

[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)


Pet*_*aut 5

您只需将该列表作为参数传递给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)


Atu*_*ind 0

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)

  • 就 sql 最佳实践而言,结尾部分不正确。很少建议在执行的 sql 中包含值,而是建议使用绑定变量。 (9认同)
  • @alko你可以发布如何在sql最佳实践中做到这一点,而不是仅仅说它“非常简单”并告诉如何不这样做?因为我曾经自己做过一两次类似 Atul Arvind 的回答的事情。 (2认同)