pygresql — вставка и возврат последовательного файла

#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.