sql >> Databáze >  >> RDS >> PostgreSQL

Seznam Pythonu do pole PostgreSQL

Všimněte si, že s psycopg2 pro pole nemusíte provádět žádné zpracování řetězců. To je považováno za špatný postup, protože je náchylný k chybám a může - v nejhorším případě - vést k otevření injekčních útoků! Vždy byste měli používat vázané parametry. V níže uvedeném kódu vytvořím novou tabulku pouze s jedním sloupcem typu TEXT[] (jako ve vaší původní otázce). Poté přidám nový řádek a aktualizuji všechny. Takže uvidíte jak INSERT a UPDATE operace (ačkoli obě jsou téměř totožné).

Existuje však jeden Python gotcha, pokud aktualizujete pouze jednu hodnotu:cur.execute očekává příkaz SQL jako první argument a iterovatelný obsahující parametry, které mají být svázány jako druhý argument. Následující nebude práce:

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

Důvodem je, že (new_values) je pythonem viděn jako new_values (závorky jsou v tomto případě vynechány, nejsou vnímány jako n-tice). To bude mít za následek chybu, že zadáte 3 hodnoty ('a' , 'b' a 'c' ) jako hodnoty, které mají být svázány, ale existuje pouze jeden zástupný symbol (%s ) v dotazu. Místo toho jej musíte zadat následovně (všimněte si přidané čárky na konci):

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

To způsobí, že Python uvidí (new_values,) jako n-tici (která je iterovatelná) s jedním prvkem, který odpovídá zástupným symbolům dotazu. Podrobnější vysvětlení koncové čárky naleznete v oficiálních dokumentech o n-ticích.

Případně můžete také napsat [new_values] místo (new_values,) , ale - podle mého názoru - (new_values,) je čistší, protože n-tice jsou neměnné, zatímco seznamy jsou proměnlivé.

Zde je tabulka, se kterou jsem testoval:

CREATE TABLE foo (
    values TEXT[]
);

A zde je kód Pythonu pro vkládání a aktualizaci hodnot:

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

Při každém spuštění kód vloží nový řádek se stejnými hodnotami pole a poté provede aktualizaci bez WHERE klauzule, takže všechny hodnoty jsou aktualizovány. Po několika provedeních to dává následující výstup:

>>> 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. Oracle Database Testing Challenge – Porovnejte data schématu

  2. Jak zobrazit serverové řazení v MySQL

  3. *UPOZORNĚNÍ* Aktualizace systému Windows ruší čistě aplikace Access – oprava je k dispozici

  4. Funkce okna Postgres a seskupení podle výjimky