PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Lista Pythona do tablicy PostgreSQL

Zauważ, że z psycopg2 nie musisz wykonywać żadnego przetwarzania ciągów dla tablic. Jest to uważane za złą praktykę, ponieważ jest podatne na błędy i może – w najgorszym przypadku – prowadzić do ataków iniekcji! Zawsze należy używać powiązanych parametrów. W poniższym kodzie utworzę nową tabelę z tylko jedną kolumną typu TEXT[] (jak w pierwotnym pytaniu). Następnie dodam nowy wiersz i zaktualizuję je wszystkie. Zobaczysz więc zarówno INSERT i UPDATE operacja (chociaż oba są prawie identyczne).

Istnieje jednak jeden problem w Pythonie, jeśli aktualizujesz tylko jedną wartość:cur.execute oczekuje instrukcji SQL jako pierwszego argumentu i iterowalnego zawierające parametry do powiązania jako drugi argument. Poniższe nie praca:

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

Powodem jest to, że (new_values) jest postrzegany przez pythona jako new_values (w tym przypadku nawiasy są odrzucane, nie są postrzegane jako krotka). Spowoduje to błąd, że podajesz 3 wartości ('a' , 'b' i 'c' ) jako wartości do powiązania, ale jest tylko jeden symbol zastępczy (%s ) w zapytaniu. Zamiast tego musisz określić to w następujący sposób (zwróć uwagę na dodany przecinek na końcu):

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

Spowoduje to, że Python zobaczy (new_values,) jako krotka (która jest iterowalna) z jednym elementem, który pasuje do symboli zastępczych zapytania. Bardziej szczegółowe wyjaśnienie końcowego przecinka znajduje się w oficjalnych dokumentach dotyczących krotek.

Alternatywnie możesz również napisać [new_values] zamiast (new_values,) , ale - moim zdaniem - (new_values,) jest czystsze, ponieważ krotki są niezmienne, podczas gdy listy są zmienne.

Oto tabela, z którą testowałem:

CREATE TABLE foo (
    values TEXT[]
);

A oto kod Pythona zarówno wstawiający, jak i aktualizujący wartości:

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

Przy każdym wykonaniu kod wstawi nowy wiersz z tymi samymi wartościami tablicy, a następnie wykona aktualizację bez WHERE klauzula, więc wszystkie wartości są aktualizowane. Po kilku wykonaniach daje to następujący wynik:

>>> 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. Jak działa KOPIUJ i dlaczego jest o wiele szybszy niż WSTAWIANIE?

  2. Ograniczenia dotyczące nazw kolumn tabeli Postgres?

  3. Filtrowanie Django JSONField

  4. GroupingError:ERROR:kolumna musi występować w klauzuli GROUP BY lub być używana w funkcji agregującej

  5. Jak zresetować sekwencję klawiszy podstawowych Postgres, gdy nie będzie ona zsynchronizowana?