Python / postgres / psycopg2: yeni eklenen satırın kimliğini alma


105

Postgres ile arayüz oluşturmak için Python ve psycopg2 kullanıyorum.

Bir satır eklediğimde ...

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)

... az önce eklediğim satırın kimliğini nasıl alırım? Denemek:

hundred = cursor.fetchall() 

RETURNING idşunları kullanırken bir hata döndürür :

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ") RETURNING id;"
hundred = cursor.execute(sql_string)

basitçe döner None.

GÜNCELLEME: Öyledir currval(bu komutu doğrudan postgres çalışmasına rağmen):

sql_string = "SELECT currval(pg_get_serial_sequence('hundred', 'id'));"
hundred_id = cursor.execute(sql_string)

Herhangi biri tavsiyede bulunabilir mi?

Teşekkürler!

Yanıtlar:


214
cursor.execute("INSERT INTO .... RETURNING id")
id_of_new_row = cursor.fetchone()[0]

Ve lütfen manuel olarak değerler içeren SQL dizeleri oluşturmayın. Değerleri ayrı ayrı geçirebilirsiniz (ve gerekir!), Bu da kaçmayı ve SQL enjeksiyonunu imkansız hale getirir:

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES (%s,%s,%s) RETURNING id;"
cursor.execute(sql_string, (hundred_name, hundred_slug, status))
hundred = cursor.fetchone()[0]

Daha fazla ayrıntı için psycopg belgelerine bakın: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries


13
Açıklığa kavuşturmak için, idin RETURNING id, seri / birincil anahtar alanının alan adı olmalıdır.
joshden

11
imleç getirme bana "alınacak sonuç yok" veriyor.
Leonid

@Leonid bunu çözdün mü?
Alison S

6
@AlisonS @Leonid Aynı hatayı aldım, ancak sorgunun RETURNING idsonuna eklemek benim için sorunu çözdü INSERT.
Banjer

Belki birazcık nota, ama önemli nokta herkes için söz: emin yalnızca imleç kullandığınızdan emin olun .Execute () ve bir imleç .mogrify () önce yürütmek () cursor.execute (bende olduğu gibi), aksi takdirde komutun () herhangi bir sonuç almayacak! Bu komuttan önce "hiçbir şey" olmadan yalnızca imleç .execute () kullanarak bir id alırsınız.
TheHeroOfTime

14

Buraya geldim çünkü benzer bir sorun yaşadım, ancak henüz RETURNING ID maddesini desteklemeyen Postgres-XC kullanıyoruz. Bu durumda şunları kullanabilirsiniz:

cursor.execute ('INSERT INTO ........')
cursor.execute ('SELECT LASTVAL ()')
lastid = cursor.fetchone () ['lastval']

Her ihtimale karşı, herkes için yararlı oldu!


4
Unutmayın - bunu iki ifadeyle yapmak, eğer bir şey veritabanına doğrudan sizden sonra, ancak lastval () komutunuz dizinin mevcut değerini döndürmeden önce (çok küçük) yarış koşulları riskini taşır.
Dave Thomas

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.