#python #postgresql #pygresql
#python #postgresql #pygresql
Вопрос:
Я использую PyGreSQL для доступа к моей базе данных. В примере использования, над которым я сейчас работаю; я пытаюсь вставить запись в таблицу и вернуть идентификатор последней строки… он же значение, созданное базой данных для моего поля ID:
create table job_runners (
id SERIAL PRIMARY KEY,
hostname varchar(100) not null,
is_available boolean default FALSE
);
sql = "insert into job_runners (hostname) values ('localhost')"
Когда я использовал db.insert(), который имел наибольший смысл, я получил «AttributeError». И когда я попробовал db.query (sql), я не получил ничего, кроме OID.
Вопрос: Используя PyGreSQL, каков наилучший способ вставлять записи и возвращать значение поля ID без выполнения каких-либо дополнительных операций чтения или запросов?
Комментарии:
1. Пожалуйста, предоставьте дополнительную информацию: фактический вызов db.insert() / db.query(), точное сообщение об ошибке, версии Postgres и PyGreSQL и т.д.
Ответ №1:
INSERT INTO job_runners
(hostname,is_available) VALUES ('localhost',true)
RETURNING id
Тем не менее, я понятия не имею о pygresql, но, судя по тому, что вы уже написали, я предполагаю, что это db.query()
то, что вы хотите использовать здесь.
Комментарии:
1. @hacker — хотя приведенный выше SQL помог, моя проблема была конкретно связана с pygresql и получением этого идентификатора обратно из базы данных.
2. Получение идентификатора обратно из базы данных является
RETURNING
частью. Я предположил, что вы знаете, как получить результат, которыйdb.query()
дает. Без этого бита он не передаст сгенерированный идентификатор обратно клиенту.3. Просто прочитайте свой собственный ответ на свой собственный вопрос 😉 OID — это не очень хороший подход, потому что у вас не всегда есть OID, я не думаю, что это
INSERT
когда-либо возвращает несколько OID (но я не уверен, потому что я никогда им не пользовался), и, наконец, вам все равно придется выводитьid
из OID. Что было бы проще сделать с помощьюSELECT
редактированияcurrval('job_runners_id_seq')
.4. @hacker — класс DBI PERL предлагает метод / атрибут ‘last_insert_id’. Это не то же самое, что «возврат». Чтение документа объясняет, что возврат аналогичен ‘select’. Спасибо, что указали мне направление, которое ответило на вопрос.
Ответ №2:
В документации PyGreSQL говорится, что если вы вызовете dbconn.запрос() с инструкцией insert / update о том, что он вернет OID. Далее говорится кое-что о списках OID, когда задействовано несколько строк.
Прежде всего; я обнаружил, что функции OID не работают. Я полагаю, что знание номеров версий библиотек и инструментов помогло бы, однако я не пытался вернуть OID.
Наконец; добавив «возвращаемый идентификатор», как предложил @hacker, pygresql просто поступил правильно и вернул набор записей с идентификатором в результирующем словаре (см. Код ниже).
sql = "insert into job_runners (hostname) values ('localhost') returning id"
rv = dbconn.query(sql)
id = rv.dictresult()[0]['id']
Ответ №3:
Предполагая, что у вас есть объект cursor cur
:
cur.execute("INSERT INTO job_runners (hostname) VALUES (%(hostname)s) RETURNING id",
{'hostname': 'localhost'})
id = cur.fetchone()[0]
Это гарантирует, что PyGreSQL корректно экранирует входную строку, предотвращая внедрение SQL.