Я начинаю вводить больше логики в базу данных, используя триггеры, представления, функции, CTE и т. Д. Когда plv8 / json выходит для postgres, я вижу, что вкладываю туда много логики.
У меня проблемы со "стандартным" способом переноса базы данных в sequel и activerecord. И sequel, и activerecord позволяют помещать произвольный код sql в файлы с отметками времени. При запуске каждого файла таблица schema_versions обновляется с указанием имени файла (или отметки времени в имени файла), в которой хранятся записи о том, какие миграции были применены к текущей базе данных.
Если на уровне базы данных выполняется много кода, это означает, что модификации существующих представлений, функций и т. Д. Следуют приведенному ниже шаблону:
Миграция 1 определяет функцию и представление, которое использует эту функцию.
-- Migration 1
create function calculate(x int) returns int as $$
return x + 1;
$$ language sql;
create view foos as (
select something, calculate(something) from a_table
);
Требования меняются, и мне нужно изменить тип функции. В Migration 2 мне нужно отбросить все объекты, зависящие от foo, и воссоздать их, скопировав все их тело - даже если в большей части другого кода не было никаких изменений!
-- Migration 2
-- Have to drop all views and functions that depend on the
-- `calculate(int)` function.
drop view foos;
create or replace calculate(x bigint) returns bigint as $$
return x + 1;
$$ language sql;
-- I could do `drop function calculate(int) cascade`,
-- but I might accidentally drop some objects that wouldn't get recreated below.
-- Now I have to recreate foo.
create view foos as (
select something, calculate(something) from a_table
);
Если я создаю систему, основанную на представлениях, функциях и триггерах, мои миграции будут заполнены дублированным кодом, и будет сложно найти последнюю версию кода. Вы могли бы сказать «не делайте этого!», Но для моих целей (электронная коммерция, доставка, транзакции) я считаю, что гораздо проще и быстрее, чтобы база данных обеспечивала целостность данных, выполняя логику внутри базы данных.
Вы можете (конечно) сбросить текущую схему базы данных (которая включает в себя все определения кода), но я думаю, что вы потеряете комментарии. И вы обычно не хотите редактировать гигантский файл, содержащий всю схему.
Есть идеи, как решить эту проблему?
Моя лучшая идея - это то, как код sql содержится в их собственных канонических файлах (app / sql / orders / shipping.sql, app / sql / orders / creation.sql и т. Д.). Все развиваются прямо на них. Всякий раз, когда приходит время выпуска, вам нужно создать новый файл миграции, посмотреть на весь измененный код с момента предыдущего выпуска, выяснить цепочку зависимостей объектов базы данных, которые необходимо удалить и воссоздать, а затем скопировать sql из канонических файлов sql в новый файл миграции сиквела / активной записи. Но это боль. : /
Мысли очень приветствуются. Надеюсь, я объяснил это достаточно хорошо, я сокращаю потребление кофеина и немного не в себе.
О, я задал аналогичный вопрос о переполнении стека: Изменение типа столбца, используемого в других представлениях Ответом была функция которые позволили мне пройти:
- sql-код для запуска
- представления базы данных для удаления и воссоздания
Функция будет извлекать определение представления, отбрасывать представления, запускать код sql, а затем воссоздавать определение представления (в обратном порядке удаления). Возможно, такая система функций поможет решить проблему копирования / вставки кода sql в файлы миграции.