Автоматизация / отслеживание миграций Knex и осознанных моделей - PullRequest
0 голосов
/ 10 октября 2018

Ситуация Недавно я начал работать над новым проектом с использованием nodejs.У меня есть опыт использования Python / Django и C # /. NET (не большой поклонник последних).Node великолепен, но я должен сказать, что мне не хватает простоты построения моделей и автоматизации миграции в Django.В настоящее время я использую инфраструктуру AdonisJS, которая использует Knex.Knex - мощная библиотека, но все миграции необходимо создавать вручную.Кроме того, ORM AdonisJS, который управляет моделями, не зависит от Knex (менеджера миграции).Вы также не определяете атрибуты полей в Моделях, которые могут иметь преимущества для динамического выполнения действий в передней и задней части.Учитывая все вышесказанное, существует много места для человеческих ошибок, недопонимания и нагрузки на лодку, требующей большего набора текста.Я знаю, что горячая вещь в наши дни состоит в том, чтобы держать его свободно и быстро, но для этого конкретного проекта я ищу немного больше структуры, чем свободно определенные модели.

Текущее состояние ЧтоЯ приземлился на создание нового класса с именем tableModel и класса полей для определения полей в табличной модели.Я уже закончил это, и я успешно пишу файлы миграции, используя усы.Я также планирую автоматически писать Модели, с которыми у меня не должно быть проблем (скрестив пальцы).

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

Допустим, я добавил «tableModel», который создает миграцию для создания таблицы Foo с полями {id (bigint), user_id (int), name (string255)}

Позже я хочудобавить поле с именем description, чтобы я просто добавил его в «tableModel», а затем выполнил команду сборки, которая создаст миграцию.Как проверить, что уже было создано, хотя я делаю только up () для описания?

Затем я хочу удалить поле имени, чтобы выделить его в "tableModel" и запустить миграцию сборки.команда.Как проверить, что было перенесено, и что теперь нужно добавить в down (). Редактировать: я бы добавил поле удаления в верхнюю часть и соответствующий откат в нижнюю часть.

Бонусный раунд Допустим, я хочу изменить user_id из intдля bigint, потому что кто делает внешний ключ просто int?Как мне проверить не только то, что нужно добавить вверх и вниз, но и проверить, нужно ли мне изменить свойство в поле.
Редактировать: просто записать вверх.и соответствующий откат к понижению

Большой вопрос По сути, как определить грязные классы "tableModels"

Возможное решение? Я думаю, что, возможно, мне нужно записать какой-нибудь тип реестра или снимок, а затем выполнить сравнение при построении миграций и / или моделей, а затем выполнить повторный захват / снимок.Если это маршрут, я должен сохранить его в файле json, записать его в саму БД или есть другой / лучший вариант.

Если я создам экземпляры tableModel как константы, могу ли я на самом деле записать обратно вфайл JS и захватить снимок как атрибут?Если это вариант, подходит ли файловая система Node и как лучше это сделать?Узел продолжает удивлять меня, так что я не буду сбит с толку, если какой-либо из этих вариантов.

Справка! Если кто-то прошел этот путь раньше или знает о каких-либо инструментах, которые я мог бы использовать,Я был бы очень признателен и заранее благодарен.Кроме того, если я двигаюсь в совершенно неправильном направлении, то, пожалуйста, дайте мне знать, я и обрабатываю, и ценю все виды обратной связи.

Пример Что следует отметить, когда я определяю "tableModel "для данной миграции или модели, это экземпляр класса, я не создаю расширенный класс, так как это не моя форма.

class tableModel {
    constructor(tableName, modelName = tableName, fields = []) {
    this.tableName = tableName
    this.modelName = modelName
    this.fields = fields
    }
// Bunch of other stuff

}

fooTableModel = new tableModel('fooTable', 'fooModel', fields = [

    new tableField.stringField('title'),
    new tableField.bigIntField('related_user_id'),
    new tableField.textField('description','Testing Default',false,true)


  ]
)

, что соответствует:

tableModel {
  tableName: 'fooTable',
  modelName: 'fooModel',
  fields:
   [ stringField {
       name: 'title',
       type: 'string',
       _unique: false,
       allow_null: null,
       fieldAttributes: {},
       default_value: null },
     bigIntField {
       name: 'related_user_id',
       type: 'bigInteger',
       _unique: false,
       allow_null: null,
       fieldAttributes: {},
       default_value: 0 },
     textField {
       name: 'description',
       type: 'text',
       _unique: false,
       allow_null: true,
       fieldAttributes: {},
       default_value: 'Testing Default' } ]

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

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

Вы можете сохранить изменения в файле DB / txt, которые могут действовать как снимки.Поэтому, если вы хотите выполнить откат к определенной миграции, вы найдете изменения (вверх / вниз), сделанные для этой мутации, и отрегулируете их соответствующим образом.

Позже я хочу добавить поле с именем description, чтобы я могпросто добавьте его в «tableModel», а затем запустите команду сборки, которая создаст миграцию.Как проверить, что уже было создано, хотя я делаю только up () для описания?

Здесь вы либо напрямую вызываете базу данных, и проверяете, какие поля уже созданы.Если поле уже занято и атрибуты совпадают, вы можете либо проигнорировать его, либо остановить транзакцию все вместе.

Бонусный раунд Допустим, я хочу изменить user_id с int на bigint,потому что кто делает внешний ключ просто int?Как проверить не только то, что нужно добавить вверх и вниз, но и проверить, нужно ли мне изменить свойство в поле.Опять же, вызовите саму БД на рассматриваемой таблице.Я знаю, что вызов SQL будет: describe [table_name];

После прочтения конца, я думаю, что вы ответили на это самостоятельно, но я думаю, что захват этих изменений будет лучше всего работать в базе данных NoSql, так как вы используетеNode или PostGres с его полем json.

0 голосов
/ 10 октября 2018

У вас смешаны нотации up и down.Они предназначены для переноса «последних» (запускает функцию up) и выполнения отката (запускает функцию down).Вверх и вниз, чтобы не относиться к удалению или добавлению столбцов таблицы.

Миграции вверх предназначены для любых изменений, а вниз - для изменения этих изменений.Поэтому, если вы хотите удалить столбец из некоторой таблицы, вы пишете команду в up, а затем пишете противоположное в down (вы добавили бы его обратно в ...), чтобы вы могли выполнить «откат»"и изменение эффективно отменено.Вы должны быть осторожны с такими вещами, поскольку вы можете оказаться в ситуации, когда вы действительно потеряете данные.

Хотите добавить столбец?Запишите его в up и опустите столбец в down.

Одним из основных моментов механизма миграции является отслеживание состояния изменений в вашей базе данных с течением времени.В общем, если вы создали таблицу в какой-то миграции, то примерно через день вы понимаете, что вам нужно удалить / добавить столбцы, обычно вы не возвращаетесь и не редактируете существующую миграцию, особенно если миграция уже была запущена.Вы просто напишите новую миграцию, чтобы удалить / добавить свой столбец.

Поскольку вы используете knex, существует пара таблиц "knex", которые создаются.По умолчанию вы ищете knex_migrations, если кто-то специально не изменил настройки, чтобы изменить его название.Эта таблица содержит все миграции, выполненные для вашей БД, для каждого пакета.Из CLI, если у вас установлен глобальный файл knex.js, вы можете запустить knex migrate:latest, и он перенесет все миграции, которые существуют в вашем каталоге, в целевую базу данных, если они еще не выполнялись.Это делается путем изучения таблицы knex_migrations.Если вы бросили изменение и вам не понравилось, и если вы правильно выполнили функцию down, вы можете вызвать knex migrate:rollback, чтобы отменить изменение.Если есть 3 файла миграции, которые еще НЕ были запущены, то при вызове knex migrate:latest все 3 из этих файлов миграции будут запускаться с новым номером пакета, который на 1 больше, чем самый последний номер пакета.И наоборот, если вы вызовете knex migrate:rollback, он найдет наибольший номер пакета (в пакете может быть более 1 миграции ...) и вызовет функцию down для всех этих файлов, эффективно откатив эти изменения.

Все это говорит о том, что knex - это инструмент "построителя запросов".У него есть куча вспомогательных функций, которые помогут вам создать sql.Лично я считаю, что это отвлекает.Зачем часами часами разбираться со всеми вспомогательными функциями, когда я могу просто запустить необработанный SQL и запустить его.Таким образом, это то, что мы сделали в нашей системе.мы используем knex.raw('') и пишем наши собственные DDL и DML.Он прекрасно работает и делает именно то, что нам нужно.Нам не нужно разбираться в магии построения запроса.

Короткий ответ: knex автоматически узнает, что для вас было, а что нет (опять же, через эту таблицу knex_migrationsсоздает для тебя ...).Вещи могут стать странными, когда они начнут включать git и другие ветки.Я рекомендую, если вы пишете миграции для какой-либо ветви и вам нужно заняться другой работой, всегда не забывайте сначала выполнить откат всех миграций, которые вы сделали в этой ветви, ДО переключения ветвей.В противном случае вы будете в странных состояниях БД, которые не совпадают с кодом приложения.

Лично я бы имел дело с обновлением моделей независимо от написания миграций.Например, если я добавляю столбец description в какую-то таблицу, то я, вероятно, хочу вручную обновить ORM, чтобы отразить изменение новой схемы БД.В общем, я обнаружил, что пытаясь использовать инструмент, который автоматически делает это для вас (скорее, если я изменяю форму, все, что происходит, пишет все нижележащие sql ...), как правило, заводит меня в кучу неприятностей, и я простотратить больше времени, пытаясь разгадать вещи.Но это только мои 2 цента:)

...