Как мне получить «id» после INSERT в базу данных MySQL с Python?


183

Я выполняю инструкцию INSERT INTO

cursor.execute("INSERT INTO mytable(height) VALUES(%s)",(height))

и я хочу получить первичный ключ.

Моя таблица имеет 2 столбца:

id      primary, auto increment
height  this is the other column.

Как я могу получить «идентификатор», после того, как я только что вставил это?


Ответы:


245

Используйте cursor.lastrowidдля получения последнего идентификатора строки, вставленного в объект курсора, или connection.insert_id()для получения идентификатора из последней вставки в этом соединении.


3
Что делать, если два процесса вставляют строку одновременно, используя одно и то же соединение. Какой идентификатор insert_idвернется?
xiaohan2012

28
@ xiaohan2012 Как 2 процесса используют одно и то же соединение?
hienbt88

5
Есть lastrowidтолько после того, как текущая транзакция совершается?
Джон Ван

4
@ hienbt88 Он, вероятно, имел в виду потоки, я сделал это, и это может вызвать проблемы, если вы не используете должным образом безопасность потоков. Я лично пытался создать новое соединение для каждого потока, что является хорошим решением, поскольку по какой-то причине фиксация (на самом деле, автокоммит) не сработала для меня, у меня возникло серьезное переплетение из-за того, что многие параллельные потоки выдавали несколько запросов в секунду.
Милан Велебит

Не работает с дублированными записями с использованием вставки, выбора и где.
e-info128

114

Также cursor.lastrowid(расширение dbapi / PEP249, поддерживаемое MySQLdb):

>>> import MySQLdb
>>> connection = MySQLdb.connect(user='root')
>>> cursor = connection.cursor()
>>> cursor.execute('INSERT INTO sometable VALUES (...)')
1L
>>> connection.insert_id()
3L
>>> cursor.lastrowid
3L
>>> cursor.execute('SELECT last_insert_id()')
1L
>>> cursor.fetchone()
(3L,)
>>> cursor.execute('select @@identity')
1L
>>> cursor.fetchone()
(3L,)

cursor.lastrowidнесколько дешевле connection.insert_id()и намного дешевле, чем другое путешествие в MySQL.


4
Почему cursor.lastrowidдешевле чем connection.insert_id()?
Мартин Тома

3
Только потому, что cursor.lastrowid автоматически устанавливается на объект курсора как часть cursor.execute () и является просто поиском атрибута. connection.insert_id () - это дополнительный ненужный вызов функции - который уже был вызван и чей результат доступен в атрибуте lastrowid.
Андрей

5
У меня просто была проблема, когда cursor.lastrowidвернули что-то другое, чем connection.insert_id(). cursor.lastrowidвернул последний идентификатор вставки, connection.insert_id()вернулся 0. Как это может быть?
Мартин Тома

1
@ moose, возможно, параллельные процессы выполняют параллельную вставку базы данных, используя одно и то же соединение.
xiaohan2012

1
@FlyingAtom, потому что это запускалось на python2 вместо python3.
Андрей

35

Спецификация Python DBAPI также определяет атрибут lastrowid для объекта курсора, так что ...

id = cursor.lastrowid

... должно работать тоже, и это, очевидно, для каждого соединения.


7
SELECT @@IDENTITY AS 'Identity';

или

SELECT last_insert_id();

2
это учитывает условия гонки, потому что вы запрашиваете последний идентификатор строки с сервера. потому что я не хочу этого беспорядка.
Джошуа Бернс


1
Я хочу отметить, что эта часть также важна: «Каждый клиент получит последний вставленный идентификатор для последнего оператора, выполненного клиентом». Таким образом, вы получите другое значение из Workbench, чем запуск точно такого же select last_insert_id()из CLI на машине Linux
кодирование

0

Это может быть просто требованием PyMySql в Python, но я обнаружил, что мне нужно назвать точную таблицу, для которой я хотел получить идентификатор:

В:

cnx = pymysql.connect(host='host',
                            database='db',
                            user='user',
                            password='pass')
cursor = cnx.cursor()
update_batch = """insert into batch set type = "%s" , records = %i, started = NOW(); """
second_query = (update_batch % ( "Batch 1", 22  ))
cursor.execute(second_query)
cnx.commit()
batch_id = cursor.execute('select last_insert_id() from batch')
cursor.close()

batch_id

Out: 5
... или любое другое правильное значение Batch_ID


@krzys_h Спасибо за просмотр этого K, но ваше редактирование не удалось в моем тестировании, и поэтому я отклонил ваше редактирование. Если вы не возражаете, также отказавшись от редактирования?
Эдвард
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.