PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Списък на Python към PostgreSQL масив

Имайте предвид, че с psycopg2 не е необходимо да извършвате обработка на низове за масиви. Това се счита за лоша практика, тъй като е податлива на грешки и може – в най-лошия случай – да доведе до отваряне на атаки с инжектиране! Винаги трябва да използвате свързани параметри. В кода по-долу ще създам нова таблица само с една колона с тип TEXT[] (както в оригиналния ви въпрос). След това ще добавя нов ред и ще актуализирам всички. Така че ще видите и двете INSERT и UPDATE операция (въпреки че и двете са почти идентични).

Въпреки това има един проблем с Python, ако актуализирате само с една стойност:cur.execute очаква SQL израза като първи аргумент и итерируем съдържащ параметрите, които трябва да бъдат обвързани като втори аргумент. Следното не работа:

from psycopg2 import connect

conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values))
conn.commit()

Причината е, че (new_values) се вижда от python като new_values (в този случай скобите се изпускат, не се виждат като кортежи). Това ще доведе до грешка, че предоставяте 3 стойности ('a' , 'b' и 'c' ) като стойности, които трябва да бъдат обвързани, но има само един заместител (%s ) в заявката. Вместо това трябва да го посочите по следния начин (забележете добавената запетая в края):

from psycopg2 import connect

conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values,))
conn.commit()

Това ще накара Python да вижда (new_values,) като кортеж (който е итерируем) с един елемент, който съвпада с заместващите места на заявката. За по-подробно обяснение на крайната запетая вижте официалните документи за кортежи.

Като алтернатива можете също да напишете [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']")


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Най-добрите инструменти за сигнали и известия за PostgreSQL

  2. Има ли начин да се дефинира именувана константа в заявка на PostgreSQL?

  3. Функция STRING_AGG() в PostgreSQL

  4. 9.6 Най-страшният турнир

  5. Граници на думите на PostgreSQL Regex?