Nano Hash - криптовалюты, майнинг, программирование

Миграция Laravel — хороший способ отключить проверки внешнего ключа

При выполнении миграции laravel я сталкиваюсь с небольшим неудобством. Я использую Ларавель 5.1.

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

Сейчас я определяю каждую миграцию следующим образом:

class CreateSomeTable extends Migration
{
    public function up()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS=0;');
        // my table definitions go here
        DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    }

    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS=0;');
        // drop table
        DB::statement('SET FOREIGN_KEY_CHECKS=1;');
    }
}

Проблема в том, что это утомительно писать и загромождает код.

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

Если есть элегантное решение, возможно ли применить его и к процессу заполнения, поскольку это тоже проблема.

Это, очевидно, очень импровизированное решение, и я спрашиваю, есть ли лучший способ сделать это. Есть ли какие-то методы beforeMigrate и afterMigrate, которые я могу переопределить, или что-то в этом роде?

А если нет, то как вы собираетесь это делать?

Буду признателен за любые идеи, мне не нравятся все варианты, которые я изложил.

15.12.2015

  • Они всегда должны запускаться в правильном порядке, если вы использовали artisan для создания миграций, и они имеют правильные временные метки. Они запускаются в порядке отметок времени. 16.12.2015
  • Да, именно это я и имел в виду, говоря о порядке файлов. Проблема в том, что иногда вы не генерируете их в правильном порядке, а иногда у вас может быть циклическая зависимость, то есть обе таблицы имеют внешние ключи, ссылающиеся друг на друга. Независимо от того, в каком порядке вы запускаете этот пример, вы получите нарушение ограничения внешнего ключа, если не отключите проверки. 16.12.2015
  • Лучший способ избежать этих проблем — сначала создать миграцию с созданием таблицы, а затем еще одну, которая создает/удаляет ключи. 16.12.2015
  • Не особенно связано, но вы также можете отключить проверку внешнего ключа следующим образом: \DB::getSchemaBuilder()->disableForeignKeyConstraints(). Не уверен, что есть лучший способ вызвать этот метод. 28.11.2016
  • У меня снова точно такая же проблема, с еще одним проектом. В качестве временного взлома я делаю именно так, как предлагается в ОП; 2 фиктивных файла миграции с отметкой времени для запуска до и после всего остального, включая и выключая проверку внешнего ключа соответственно. Я считаю, что система миграции Laravel в корне ошибочна. Просмотр кода создания таблицы, разделенного между всеми этими файлами, уродлив и неудобен. С этого момента я собираюсь поместить все в один файл миграции, с отключенными и включенными проверками внешнего ключа в начале и в конце, а вся логика схемы четко изложена между ними. 08.12.2016

Ответы:


1

У меня была аналогичная задача, когда Lumen / Laravel начали использовать Passport, и мне пришлось отказаться от предыдущей реализации сервера oauth с lucadegasperi/oauth2-server-laravel.

Наконец-то мне удалось добиться успеха, создав 2 миграции, где первая очищает внешние ключи, а вторая фактически удаляет таблицы.

Мне пришлось использовать даты до миграции Laravel's Passport (2016-06-01), чтобы они быть казнен раньше тех.

2016_05_31_000000_clear_old_oauth_relations.php

//...
class ClearOldOauthRelations extends Migration
{
    public function up()
    {
        Schema::disableForeignKeyConstraints();
        // drop foreign keys
        Schema::table('oauth_access_tokens', function (BluePrint $table) {
            $table->dropForeign('oauth_access_tokens_session_id_foreign');
        });
        //...
        Schema::enableForeignKeyConstraints();
    }
    //...
}

А во втором файле 2016_05_31_000001_clear_old_oauth.php

//...
public function up()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('oauth_access_tokens');
    //...
    Schema::enableForeignKeyConstraints();
}
//...
30.01.2017
  • Это действительно приятно! Это было добавлено только недавно или какое-то время было в laravel, и я просто не заметил этого, когда у меня возникла эта проблема? 30.01.2017
  • Привет @Pavlin, я не знаю, когда это было добавлено в Laravel / Lumen. Обратите внимание, что вам нужно будет найти имена ограничений внешнего ключа, например. PhpMyAdmin (Структура -> Отношения) 30.01.2017
  • Это было добавлено в Laravel начиная с версии 5.2. 10.05.2017

  • 2

    Я сделал это, извлекая логику внешнего ключа в отдельный файл миграции. Это помогло мне:

    • Отключите ограничения внешнего ключа.
    • Надежно удалите базу данных, если она существует.

    В коде:

    //file: 2017_06_19_230601_fk_postuser_table.php
    
    public function down()
    {
            Schema::disableForeignKeyConstraints();
            Schema::dropIfExists('post_user');
    }
    
    20.06.2017

    3

    Еще один важный аспект, о котором следует помнить, — сначала удалить ForeignKey, а затем столбец. Удаление столбца сначала вызывает ошибку:

    Cannot drop index 'tableName_columnName_foreign': needed in a foreign key constraint

    Правильный порядок имеет значение:

        public function down()
        {
            Schema::table('tableName', function (Blueprint $table) {
                $table->dropForeign(['columnName']); // fk first
    
                $table->dropColumn('columnName'); // then column
            });
        }
    
    19.02.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

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

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..