Python / postgres / psycopg2 : 방금 삽입 된 행의 ID 가져 오기


99

저는 Python과 psycopg2를 사용하여 postgres에 인터페이스하고 있습니다.

행을 삽입하면 ...

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

... 방금 삽입 한 행의 ID를 어떻게 얻습니까? 견딜 수 없는:

hundred = cursor.fetchall() 

사용하는 동안 오류를 반환합니다 RETURNING id.

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)

단순히 반환합니다 None.

업데이트 : 마찬가지로 currval(이 명령을 postgres에 직접 사용하더라도) :

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

누구든지 조언 할 수 있습니까?

감사!

답변:


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

그리고 값을 포함하는 SQL 문자열을 수동으로 작성하지 마십시오. 값을 개별적으로 전달할 수 있으므로 이스케이프 할 필요가없고 SQL 삽입이 불가능합니다.

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]

자세한 내용은 psycopg 문서를 참조하십시오 : http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries


12
명확히하기 위해 idin RETURNING id은 직렬 / 기본 키 필드의 필드 이름이어야합니다.
joshden

9
커서 fetchone이 "가져올 결과가 없음"을 제공합니다.
레오 니드

@Leonid 당신이 이것을 알아 냈습니까?
Alison S

4
@AlisonS @Leonid 동일한 오류가 있었지만 쿼리 RETURNING id끝에 추가 하면 INSERT문제가 해결되었습니다.
Banjer

어쩌면 조금 참고하지만, 중요한 점은 모든 사람을위한 언급 : 당신이 전용 커서를 사용하고 있는지 확인 .Execute를 () 가 아닌 커서를 .mogrify () 전과 실행 () cursor.fetchone (내 경우처럼) 그렇지 않으면 명령 () 결과가 없습니다! 명령 전에 "anything"없이 커서 .execute () 만 사용 하면 ID를 받게됩니다.
TheHeroOfTime

14

비슷한 문제가 있었기 때문에 여기에 왔지만 아직 RETURNING ID 절을 지원하지 않는 Postgres-XC를 사용하고 있습니다. 이 경우 다음을 사용할 수 있습니다.

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

누구에게나 유용했던 경우를 대비하여!


4
기억하십시오-두 개의 명령문에서 수행하면 경쟁 조건의 (매우 작은) 위험이 발생합니다. 만약 무언가가 사용자 바로 뒤에 데이터베이스에 행을 삽입하지만 lastval () 명령이 시퀀스의 현재 값을 반환하기 전에 발생합니다.
Dave Thomas

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.