postgresql: как получить первичные ключи строк, вставленных с помощью copy_from? - PullRequest
3 голосов
/ 03 ноября 2011

Цель состоит в следующем: у меня есть набор значений для входа в таблицу A и набор значений для перехода в таблицу B. Значения входят в B ссылочные значения в A (через внешний ключ), поэтому после вставки значений A мне нужно знать, как ссылаться на них при вставке значений B. Мне нужно, чтобы это было как можно быстрее.

Я сделал вставку значений B с массовой копией из:

def bulk_insert_copyfrom(cursor, table_name, field_names, values):
    if not values: return

    print "bulk copy from prepare..."
    str_vals = "\n".join("\t".join(adapt(val).getquoted() for val in cur_vals) for cur_vals in values)
    strf = StringIO(str_vals)
    print "bulk copy from execute..."
    cursor.copy_from(strf, table_name, columns=tuple(field_names))

Это было намного быстрее, чем делать запрос INSERT VALUES ... RETURNING id. Я хотел бы сделать то же самое для A значений, но мне нужно знать id s вставленных строк.

Есть ли способ выполнить массовое копирование таким способом, кроме как получить поле id (первичный ключ) вставленных строк, так что я знаю, какой id связан с каким value

Если нет, то как лучше всего достичь моей цели?

РЕДАКТИРОВАТЬ: Пример данных по запросу:

a_val1 = [1, 2, 3]
a_val2 = [4, 5, 6]
a_vals = [a_val1, a_val2]

b_val1 = [a_val2, 5, 6, 7]
b_val2 = [a_val1, 100, 200, 300]
b_val3 = [a_val2, 9, 14, 6]
b_vals = [b_val1, b_val2, b_val3]

Я хочу вставить a_vals, затем вставить b_vals, используя внешние ключи вместо ссылок на объекты списка.

Ответы [ 2 ]

4 голосов
/ 04 ноября 2011

Сгенерируйте идентификаторы самостоятельно.

  1. НАЧАЛО транзакции
  2. Блокировка таблицы при
  3. вызове nextval () - это ваш первый идентификатор
  4. генерацияваша копия с идентификаторами на месте
  5. такая же для таблицы b
  6. вызов setval () с вашим окончательным идентификатором + 1
  7. транзакция COMMIT

вшаг 2 вы, вероятно, хотите заблокировать отношение последовательности тоже.Если код вызывает nextval () и хранит этот идентификатор где-то, он может быть уже использован к тому времени, когда он его использует.

Немного не по теме: есть параметр «кеш», который можно установить, если у вас естьмного бэкэндов делают много вставок.Это увеличивает счетчик в блоках.

http://www.postgresql.org/docs/9.1/static/sql-createsequence.html

0 голосов
/ 11 октября 2017

На самом деле вы можете сделать это по-другому, что вам нужно:

  • Начать транзакцию
  • Создать временную таблицу с той же (или почти такой же) схемой
  • COPY данные в эту временную таблицу
  • Выполнение регулярного INSERT INTO .. FROM temp_table ... RETURNING id, other_columns
  • Подтверждение

взято из здесь (в c #, ното же самое)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...