Python / postgres / psycopg2: nhận ID của hàng vừa được chèn


99

Tôi đang sử dụng Python và psycopg2 để giao diện với postgres.

Khi tôi chèn một hàng ...

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

... làm cách nào để lấy ID của hàng tôi vừa chèn? Cố gắng:

hundred = cursor.fetchall() 

trả về lỗi khi sử dụng 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)

chỉ đơn giản là trả lại None.

CẬP NHẬT: Cũng vậy currval(mặc dù sử dụng lệnh này trực tiếp vào postgres hoạt động):

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

Bất cứ ai có thể tư vấn?

cảm ơn!

Câu trả lời:


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

Và vui lòng không xây dựng các chuỗi SQL chứa các giá trị theo cách thủ công. Bạn có thể (và nên!) Chuyển các giá trị một cách riêng biệt, làm cho việc thoát không cần thiết và không thể chèn 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]

Xem tài liệu psycopg để biết thêm chi tiết: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries


12
Chỉ cần làm rõ, idin RETURNING idphải là tên trường của trường khóa nối tiếp / khóa chính.
joshden

9
con trỏ fetchone cho tôi "không có kết quả nào để tìm nạp".
Leonid

@Leonid bạn đã tìm ra điều này chưa?
Alison S

4
@AlisonS @Leonid Tôi đã gặp lỗi tương tự, nhưng việc thêm RETURNING idvào cuối INSERTtruy vấn đã sửa lỗi đó cho tôi.
Banjer

Có thể chỉ là một lưu ý nhỏ, nhưng điểm quan trọng cần đề cập cho mọi người: Đảm bảo rằng bạn chỉ sử dụng con trỏ .execute () chứ không phải con trỏ .mogrify () trước lệnh thi hành () , nếu không (như trong trường hợp của tôi) cursor.fetchone () sẽ không có bất kỳ kết quả! Bằng cách chỉ sử dụng con trỏ .execute () mà không có "bất cứ thứ gì" trước lệnh đó, bạn sẽ nhận được một id.
TheHeroOfTime

14

Tôi đã kết thúc ở đây vì tôi gặp sự cố tương tự, nhưng chúng tôi đang sử dụng Postgres-XC, chưa hỗ trợ mệnh đề RETURNING ID. Trong trường hợp đó, bạn có thể sử dụng:

cursor.execute ('CHÈN VÀO ........')
cursor.execute ('CHỌN LASTVAL ()')
lastid = cursor.fetchone () ['lastval']

Chỉ trong trường hợp nó hữu ích cho bất kỳ ai!


4
Chỉ cần nhớ - thực hiện nó trong hai câu lệnh như vậy sẽ dẫn đến rủi ro (rất nhỏ) về điều kiện chủng tộc, nếu thứ gì đó chèn một hàng vào cơ sở dữ liệu ngay sau bạn, nhưng trước khi lệnh lastval () của bạn trả về giá trị hiện tại của chuỗi.
Dave Thomas

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.