原理迁移:为mysql和postgresql创建代码 [英] Doctrine migrations: create code for mysql and postgresql
问题描述
我在Symfony 3.4.4项目中使用Doctrine ORM 2.6.1。
我的某些实例在MySQL数据库上工作,某些在Postgresql上工作,还有一些安装甚至可以访问MicosoftSQL服务器。无需对我的项目或实体进行任何特殊更改即可正常工作,我只需要配置相应的连接参数。
I am using Doctrine ORM 2.6.1 in a Symfony 3.4.4 project. Some of my instances work on a MySQL database, some on Postgresql, and a few installations even access a MicosoftSQL server. This works fine without any special changes to my project or entities, I only have to configure the corresponding connection parameters.
但是:如果我创建迁移,则在迁移文件中只会创建与当前数据库连接兼容的语句。
But: if I create migrations, only statements compatible with the current database connection are created in the migration file.
我使用postgres连接开发,所以我只生成postgresql语句,例如:
I develop with a postgres-conncection, so I only produce postgresql-statements, like:
class Version20180430083616 extends AbstractMigration
{
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('DELETE FROM document_category');
$this->addSql('DROP SEQUENCE document_category_id_seq CASCADE');
$this->addSql('DROP TABLE document_category');
}
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
//...
}
}
我的问题:如何告诉迁移捆绑包为每个平台创建语句,例如:
My Question: How can I tell the migrations bundle to create statements for each platform, like:
class Version20180430083616 extends AbstractMigration
{
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
if($this->connection->getDatabasePlatform()->getName() == 'postgresql'){
$this->addSql('DELETE FROM document');
$this->addSql('DELETE FROM document_category');
$this->addSql('DROP SEQUENCE document_category_id_seq CASCADE');
$this->addSql('DROP TABLE document_category');
} else if($this->connection->getDatabasePlatform()->getName() == 'mysql'){
...
} else if ($this->connection->getDatabasePlatform()->getName() == 'mssql') { // MicrosoftSQL ?
...
}
}
}
编辑:
因此,我认为我的问题的唯一解决方案是定义多个数据库连接和实体管理器,并始终创建一个每个连接类型的不同迁移。根据这篇文章,我可以将几个连接定义为:
So, I think the only solution to my problem is to define multiple database connections and entity managers, and to always create a distinct migration for each connection type. According to this article, I can define several connections as:
推荐答案
我找到了可行的解决方案:
I found a doable solution:
inf config.yml我定义了一个连接每种数据库类型一个EntityManager:
inf config.yml I define one connection and one EntityManager per database type:
doctrine:
dbal:
default_connection: pgdb
connections:
pgdb:
driver: pdo_pgsql
host: db
port: 5432
name: pgdb
user: postgres
password: example
charset: utf8
mapping_types:
enum: string
mysql:
driver: pdo_mysql
host: mysqlhost
port: 3306
name: mydb
dbname: mydb
user: root
password: xxx
charset: utf8mb4
default_table_options:
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
mssql:
driver: pdo_sqlsrv
host: mssqlhost
port: 1433
name: msdb
dbname: testdb
user: sa
password: xxx
charset: utf8
mapping_types:
enum: string
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.cache_dir%/doctrine/orm/Proxies'
proxy_namespace: Proxies
entity_managers:
default:
connection: pgdb
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
AppBundle: ~
my:
connection: mydb
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
AppBundle: ~
ms:
connection: msdb
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
AppBundle: ~
然后,我可以发出diff命令3次,而不是只发出一次
Then, I can issue the diff-command 3 times instead of only once
$ bin/console doctrine:migrations:diff --em=default
$ bin/console doctrine:migrations:diff --em=my
$ bin/console doctrine:migrations:diff --em=ms
这将创建三个迁移,每个迁移以隔离线开始:
This creates three migrations each starting with a fence line:
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mssql', 'Migration can only be executed safely on \'mssql\'.');
其中,我将 abortIf
交换为 skipIf
,这样,如果当前迁移是针对其他数据库类型,则迁移过程不会中止,而只是跳过:
in which I exchange abortIf
by skipIf
, such that the migration process is not aborted if the current migration if for a different database type, but just skipped:
$this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mssql', 'Migration can only be executed safely on \'mssql\'.');
我希望这对某人有帮助。
I hope this helps somebody.
这篇关于原理迁移:为mysql和postgresql创建代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!