- Оригинальный адрес:Sharing databases between Laravel applications
- Оригинальный автор:Michael Dyrynda
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:Elliott Zhao
вводить
если вы оказались вTwitterСледуйте за мной на , возможно, вы видели, как я публикую некоторые из моих повседневных работ. У нас есть личный кабинет для клиентов и внутренняя CRM, которые работают с одной и той же основной базой данных.
CRM была создана до того, как я работал на своего нынешнего начальника, а личный кабинет был создан мной как аутсорсером в начале 2017 года. Сама область для участников — это новое приложение Laravel, а CRM — это полностью написанное на заказ программное обеспечение.
304/5000 Как аутсорсер, у меня есть неполная копия базы данных, и мне удалось реконструировать модель Eloquent из схемы базы данных, создавфабрика, чтобы иметь возможность писать тесты для приложения членства.
В конце 2017 года мы начали миграцию нашей CRM на Laravel, чтобы немного модернизировать кодовую базу, придать ей стандартную структуру и легко ее изменить. Теперь, когда у нас есть два приложения Laravel, мы начинаем думать, как обмениваться данными между ними.
Красноречивая модель
Модель базы данных является самым простым частью. Для этого мы используем композитор для создания пакета для каждой модели создания таблицы базы данных и использовать их какvcs-репозиторий. Это позволяет нам делиться этими моделями без публикации через Packagist.
Каждая из моделей в этом пакете является продолжением собственной базовой модели, которая устанавливает соединения для каждой базы данных и содержит минимальное количество логики, которая может соединить их вместе.
Мы стараемся, чтобы модель пакета содержала только отношения между собой, а также некоторые общие методы и поведение. Идея состоит в том, что каждое приложение, которое их использует, будет расширять их по мере необходимости и реализовывать свою собственную специфическую логику.
мигрировать
Миграция — это то место, где все становится немного сложнее. Хотя у нас есть база данных, которая технически принадлежит приложению CRM, миграция должна работать для любого приложения, которое будет обращаться к данным в ней. Тогда возникает вопрос: «Какая программа отвечает за управление схемой базы данных?»
В лиравеconfig/database.php
文件中附带多个数据库连接,向您显示各种驱动的可用性。我们简单的定义几个都使用
подключение драйвера mysql.
У нас есть некоторые требования для управления схемой базы данных:
- Любое приложение, использующее базу данных, не должно нести ответственность за управление миграциями.
- Миграцию можно использовать для тестирования
- Если возможно, мы хотели бы использовать функцию миграции Laravel.
Первые два требования довольно просты, если предположить, что мы можем каким-то образом решить третье.
автономная утилита
Мне потребовалось много времени, чтобы собрать такой инструмент, как Artisan, который фокусируется только на функциях миграции и заполнения базы данных.Nomad. Для управления миграцией баз данных для многих приложений Nomad можно включить в отдельный проект Composer, например.Vagabond.
Затем проект Vagabond представляется в виде пакета, который вы можете использовать в качестве репозитория VCS и использовать поставщика услуг, который указывает Laravel загружать миграции вместе со всеми миграциями, которые могут существовать в приложении, которое его использует.
// 在你的 Vagabond 项目的服务提供者中
public function boot()
{
$this->loadMigrationsFrom(dirname(__FILE__).'/../database/migrations');
}
Кочевник в действии
Первая проблема, с которой мы столкнулись с путем Nomad, заключалась в том, что если вы не укажете в файле миграции соединение, на котором должна выполняться миграция, все они будут выполняться на вашем соединении по умолчанию.
// 在您的迁移文件中
public function up()
{
Schema::connection('the_connection')->create('table', function (Blueprint $table)
{
//
}
}
Вторая проблема заключается в том, что, хотя приложение Laravel будет запускать миграции в правильном соединении, оно будет отслеживать миграции в соединении по умолчанию.всеМиграции, т. е. если вы запускаете миграции для трех разных подключений, вся история миграции будет находиться в подключении приложения по умолчанию.migrations
поверхность.
Почему это проблема? Если у вашего пользователя базы данных есть достаточные привилегии, он будет пытаться выполнять одну и ту же миграцию снова и снова в базе данных, где эти таблицы уже существуют.
Эта проблема возникает, если у вас есть много разных приложений, которые используют файл централизованной миграции и каждый раз пытаются выполнить одну и ту же миграцию.
Чтобы решить эту проблему, мы переносим проектdatabase/migrations
Папки создаются для каждой подключенной миграции.
database/migrations/
/crm
/gis
/coverage
Сделав это, мы теперь можем использовать для различных команд миграцииpath
иdatabase
параметры, которые позволяют нам явно запускать миграции для каждого соединения:php nomad migrate --database=gis --path=database/migrations/gis
. Это гарантирует, что работает толькоgis
мигрировать иgis
база данныхmigrations
История запущенных миграций отслеживается в таблице.
Теперь это отвечает требованиям 1 и 3; теперь мы используем миграции в стиле Laravel для отдельной базы данных,иУ нас также есть автономные приложения, которые могут запускать миграции. Это означает, что мы можем запускать миграцию для определенного подключения к базе данных в любом месте нашего кода, который а) имеет доступ к серверу базы данных и б) имеет пользователя с достаточными привилегиями.
Используйте общие миграции и модели в тестах
Еще одна проблема, с которой мы столкнулись, — запуск тестов.
В нашей тестовой среде мы используем LaravelRefreshDatabase
функция, которая интеллектуально создает и удаляет всю базу данных для каждого теста. Однако на момент написания этой статьи, хотя все миграции выполняются правильно,но он удалит таблицу только при подключении к базе данных по умолчанию.
Это означает, что если мы тестируем приложение, которое использует свою собственную базу данных, а также общую базу данных, каждый тест будет терпеть неудачу, потому что Laravel попытается выполнить миграцию без разрыва соединений. К этому,Sepehr Lajevardiсуществует одинрешение,Keith DamianiПокажи мне путь.
Функция, упомянутая в предложении Sepehr, переопределяет значение по умолчанию Laravel с помощью метода, который ищет свойства из массива соединений таблицы для удаления.refreshTestDatabase
метод.
Конфигурация базы данных
Теперь, когда вы упаковали свои модели и миграции в свой собственный репозиторий, это последнее, что вы не хотите делать. Вручную скопированная из проекта в другой проект сама конфигурация.
Laravel фактически позволяет легко объединить конфигурацию сторонних пакетов с основной конфигурацией. В нашем производственном приложении, в нашей конфигурации базы данныхнетНастройте любое соединение.
Вместо этого эта функциональность находится внутри поставщика услуг для каждого подключения к базе данных. У нас есть провайдер верхнего уровня, каждый из которых может быть расширен, по умолчанию каждому провайдеру нужно только определить защищенное свойство:$connectionName
.
ты сможешьздесьСм. отдельный пример этой функции.
Что вам нужно сделать в вашем приложении, так это добавить поставщика услуг в вашconfig/app.php
файл в массиве provider и определите необходимые переменные окружения для каждого подключения.
Непрерывная интеграция
Последняя часть головоломки, которая нам остается, — запустить тесты в конвейере CI. Для нас даBitBucket.
Поскольку наша существующая база данных содержит множествоENUM
поля (я не рекомендую их использовать, тем более, что они не поддерживаются этой библиотекой --doctrine/dbal
-- Laravel для функции миграции), мы должны использовать MySQL в нашей тестовой среде.
Использование контейнеров в конвейере непрерывной интеграции упрощает запуск службы MySQL, однако не сразу понятно, как настроить несколько баз данных. Поскольку образ MariaDB, который мы использовали, не позволял указывать связанный порт, несколько служб базы данных пытались прослушивать один и тот же порт (3306) и впоследствии не запускались, что приводило к сбою набора тестов.
Решение очень простое, просто я не знал его раньше: используйте клиент MySQL для создания базы данных до запуска набора тестов.
твойbitbucket-pipelines.yml
Файл должен выглядеть так:
image: php:7.1.15
pipelines:
default:
- step:
deployment: test
caches:
- composer
script:
- apt-get update && apt-get install -y unzip git mysql-client
- docker-php-ext-install pdo_mysql
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- cp -n .env.example .env
- export DB_USERNAME=root
- export DB_DATABASE=first_db
- export DB_PASSWORD=supersecret
- export DB_SECOND_USERNAME=root
- export DB_SECOND_DATABASE=second_db
- export DB_SECOND_PASSWORD=supersecret
- export DB_THIRD_USERNAME=root
- export DB_THIRD_DATABASE=third_db
- export DB_THIRD_PASSWORD=supersecret
- composer install
- php artisan key:generate
- mysql -uroot -psupersecret -h127.0.0.1 -e 'create database second_db; create database third_db;'
- vendor/bin/phpunit --colors=always -c phpunit.xml
services:
- mariadb
definitions:
services:
mariadb:
image: mariadb:5.5
environment:
MYSQL_DATABASE: 'first_db'
MYSQL_ROOT_PASSWORD: 'supersecret'
export
Эти строки настроены для каждой из трех баз данных, с которыми работает наше приложение. Мы разрешаем сервису MariaDB использоватьMYSQL_DATABASE
Переменные среды для настройки первой базы данных, а затем создания с помощью клиента MySQL.second_db
иthird_db
.
MYSQL_ROOT_PASSWORD
Переменная определена как статическая строка, потому что я не понял, как ввести случайный пароль на этапе развертывания, но если вы знаете, как это сделать, сообщите мне!
в заключении
Если вам нужно использовать приложение, которое совместно использует две или более баз данных, я надеюсь, что вы узнали что-то об управлении ими и их использовании в этой статье.
Охватывает следующее:
- Упакованные модели и независимые миграцииVagabond project
- использоватьNomadЗапустите миграцию как отдельное приложение
- Обработка нескольких подключений к базе данных в тесте
- использоватьBitBucket PipelinesУспешно запускать тесты в нескольких базах данных
Из-за отделения приложения от базы данных один фактор, который мы должны учитывать, — это то, как и когда должна выполняться миграция, поскольку теперь нам нужно выполнить ее как отдельную операцию. Конечно, это будет варьироваться в зависимости от конкретного случая, и нам нужно обязательно протестировать каждое приложение, чтобы убедиться, что мы не вносим критические изменения в базу данных.
Мне потребовалось несколько месяцев, чтобы заставить его работать, поэтому я надеюсь, что когда-нибудь в будущем я смогу сэкономить вам время, если вы окажетесь в ситуации, похожей на мою!
благодарныйKeith DamianiиSepehr LajevardiУкажите последнюю часть моей головоломки, которая отсутствует.
Jake Bennettсо мной в веб-подкасте North Meets Southepisode 43Такое поведение миграции обсуждается в .
Если у вас есть какие-либо вопросы по поводу чего-либо, описанного в этой статье, или у вас есть предложения по улучшению, не стесняйтесь писать в Твиттере.предложить.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.