我有一个列表:Python列表到PostgreSQL阵列
[u'ABC', u'DEF', u'GHI']
我有将其插入到一个PostgreSQL数组: (ALTER TABLE "aTable" ADD COLUMN "Test" text[];
)
用于添加数据到PostgreSQL的语法是:
update "aTable" SET "Test" = '{"ABC", "DEF", "GHI"}'
如何将列表转换为正确的格式?
我有一个列表:Python列表到PostgreSQL阵列
[u'ABC', u'DEF', u'GHI']
我有将其插入到一个PostgreSQL数组: (ALTER TABLE "aTable" ADD COLUMN "Test" text[];
)
用于添加数据到PostgreSQL的语法是:
update "aTable" SET "Test" = '{"ABC", "DEF", "GHI"}'
如何将列表转换为正确的格式?
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
将导致对,
update "aTable" SET "Test" = '{"ABC", "DEF", "GHI"}'
在SQL处理变量的正确方法是绑定变量的使用。据我所知,这对于MySQL和Oracle DB来说至关重要,我相信PostgreSQL也是如此。
所以更好的代码是沿线
def as_array(l):
l2str = ','.join('"{}"'.format(x) for x in l)
return '{{{}}}'.format(l2str)
query = '''update "aTable" SET "Test" = %s'''
lst = [u'ABC', u'DEF', u'GHI']
cur = conn.cursor()
cur.execute(query, as_array(lst))
其中conn是到PostgreSQL数据库的连接。
您只需将该列表作为参数传递给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])
请注意,使用psycopg2
您不需要为数组执行任何字符串处理。这被认为是不好的做法,因为它容易出错,并且可能 - 在最坏的情况下 - 导致打开注入攻击!你应该总是使用绑定参数。在下面的代码中,我将创建一个只有一列的新表格,其类型为TEXT[]
(如您的原始问题)。然后,我将添加一个新行,并更新所有行。所以你会看到一个INSERT
和UPDATE
操作(尽管两者几乎完全相同)。
有一个Python的疑难杂症但如果你只有一个值更新:cur.execute
预计包含的参数被绑定为第二个参数的SQL语句作为第一个参数和迭代。下面就不工作:
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values))
的原因是(new_values)
被蟒蛇视为new_values
(括号中在此情况下下降,他们不被视为元组)。这将导致错误提供3个值('a'
,'b'
和'c'
)作为要绑定的值,但查询中只有一个占位符(%s
)。相反,你必须按如下方式指定它(注意在末尾加逗号):
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values,))
这将会使Python看到(new_values,)
作为一个元组(这是一个迭代器)一个元素,它匹配查询占位。有关尾部逗号的更详细说明,请参阅the official docs on tuples。
或者,你也可以写[new_values]
代替(new_values,)
,但是 - 在我看来 - (new_values,)
是清洁元组是不可改变的,而列表是可变的。
这里与我测试表:
CREATE TABLE foo (
values TEXT[]
);
而这里的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()
在每次执行时,该代码就会插入新行使用相同的数组值,然后执行没有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']")
这是一个非常简单的任务,到目前为止您尝试过了什么? – alko