Ссылка на значения RETURN в последовательных инструкциях INSERT внутри транзакции (в Postgres) - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь вставить несколько записей в несколько таблиц, все в одной транзакции.В этом случае его генерируют некоторые фиктивные данные.Меньшие подмножества этой последовательности вставки будут использоваться в 'production'.

Вставляемые записи:

  1. an 'account'
  2. a 'gist '
  3. a' версия 'gist
  4. несколько' файлов ', представляющих фактическое содержание версии gist

Схема, доступная здесь для справки: https://github.com/thomasgwatson/thegistofit/tree/master/sql

Моя текущая итерация выглядит следующим образом

BEGIN;

INSERT INTO account (email, name, password_hash)
VALUES
  (text 'HAH@YAY.COM', text 'HAH', text 'HASHHASH')
RETURNING account_id AS new_account_id;

INSERT INTO gist (account_id)
SELECT account_id from new_account_id
RETURNING gist_id AS new_gist_id;

INSERT INTO version (gist_id, title)
SELECT gist_id, 'my gist' from new_gist_id
RETURNING version_id AS new_version_id;

INSERT INTO file (langauge, file_name, content)
VALUES
  (text 'python', text 'first.py', text 'asfoasdfj'),
  (text 'python', text 'second.py', text 'ipsum asdfasdf'),
  (text 'python', text 'third.py', text 'okaoskdaoskd')
RETURNING file_id AS new_file_ids;

INSERT INTO version_file (version_id, file_id)
-- need to do the cartesian joint here
SELECT version_id, file_id from new_version_id, new_file_ids;


COMMIT;

Я пробовал различные способы сделать это в PostgresQL, но безрезультатно.Поиск общих табличных выражений (предложения WITH и AS) был одним из основных потоков.Тем не менее, одна строка из документации может быть тем, что меня тонет:

Тонкий пример приведенного выше примера состоит в том, что предложение WITH присоединено к INSERT, а не к SEL-SELECT в INSERT.Это необходимо, поскольку операторы, изменяющие данные, допускаются только в предложениях WITH, которые прикреплены к оператору верхнего уровня.Однако применяются обычные правила видимости WITH, поэтому можно сослаться на выходные данные оператора WITH из под-SELECT.

из https://www.postgresql.org/docs/current/queries-with.html

Мета-комментарий

  1. Использование DataGrip как что-то вроде мусора, но это меня не спасает.
  2. Сообщения об ошибках SQL, кажется, не очень помогают, вероятно, что они имеют немного другую мысленную модель, чем сообщения об ошибках, которые яраньше
  3. Мне было бы более чем удобно использовать Knex / Node или Psycopg2 / Python для абстрагирования транзакций, операторов INSERT и для обработки там данных.Попытка заставить его работать с чистым SQL

1 Ответ

0 голосов
/ 20 ноября 2018

К счастью, я предложил SQL-оператор, который выполняется!

BEGIN;

with new_account as (
  INSERT INTO account (email, name, password_hash)
  VALUES
    (text 'HAH@YAY.COM', text 'HAH', text 'HASHHASH')
  RETURNING account_id
), new_gist as (
  INSERT INTO gist (account_id)
  SELECT account_id from new_account
  RETURNING gist_id
), new_version as (
  INSERT INTO version (gist_id, title)
  SELECT gist_id, 'my gist' from new_gist
  RETURNING version_id
), new_files as (
  INSERT INTO file (langauge, file_name, content)
  VALUES
    (text 'python', text 'first.py', text 'ipsum hhb'),
    (text 'python', text 'second.py', text 'ipsum iug'),
    (text 'python', text 'third.py', text 'ipsum thd')
  RETURNING file_id
)

INSERT INTO version_file (version_id, file_id)
-- yes, doing a cartesian joint here
SELECT version_id, file_id from new_version, new_files;

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