Я начинаю перемещать больше логики в базу данных, используя триггеры, представления, функции, CTE и т. Д. Когда plv8/json выходит для postgres, я вижу, что я размещаю там много логики.Управление изменениями базы данных
У меня возникли проблемы со стандартным способом миграции баз данных в продолжении и activerecord. Оба сиквела и 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
);
Изменение требований, и мне нужно изменить тип функции. В Миграция 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 в новый файл миграции продолжения/activerecord. Но это боль. :/
Мысли приветствуются. Надеюсь, я объяснил это достаточно хорошо, я сокращаю потребление кофеина, и я немного подлый.
О, я задал подобный вопрос о переполнении стека: Changing the type of a column used in other views Ответ функция, позвольте мне передать:
- SQL кода для запуска
- представления базы данных, чтобы удалить и заново
Функция будет извлекать определение вида, удалять представления, запускать код sql, а затем воссоздавать определение представления (в обратном порядке отбрасывания). Возможно, такая функция поможет решить проблему копирования/вставки кода sql в файлы миграции.
https://github.com/nkiraly/DBSteward выглядит как интересный подход к решению этой проблемы. –
Привет, я являюсь соавтором DBSteward. Я знаю, что прошло почти четыре года с тех пор, как вы задали этот вопрос, но мы все еще активно развиваем DBSteward. Мне интересно узнать, не сделали ли вы или не использовали DBSteward, и каков ваш опыт, или почему это не решило вашу проблему. –