Ber*_*tuz 6 postgresql symfony doctrine-orm doctrine-migrations
我在我的 Symfony 项目中使用了学说,通过连接到一个已经存在的 postgres 数据库。
DB 有几个模式,但 symfony 应用程序只会使用它自己的模式。Entity我创建的第一个类如下:
namespace Belka\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="app_auth.User", schema="app_auth")
*/
class User {
/**
* @ORM\Column(type="string")
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
*/
private $username;
/**
* @ORM\Column(type="string")
*/
private $email;
/**
* @ORM\Column(type="string")
*/
private $password;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,Entity正在指定自己的 schema app_auth。接下来,我尝试使用迁移包。因此,我安装并配置了它,以便只考虑我的架构:
摘录config.yml:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
schema_filter: ~^app_auth\..*~
Run Code Online (Sandbox Code Playgroud)
摘录config_dev.yml:
doctrine_migrations:
dir_name: "%kernel.root_dir%/../.container/update/DoctrineMigrations"
namespace: Application\Migrations
table_name: "app_auth.migration_versions"
name: Application Migrations
Run Code Online (Sandbox Code Playgroud)
我运行差异:
php app/console doctrine:migrations:diff
Run Code Online (Sandbox Code Playgroud)
不幸的是,生成的迁移类如下:
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20160422171409 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
}
/**
* @param Schema $schema
*/
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\'.');
$this->addSql('CREATE SCHEMA app_auth');
}
}
Run Code Online (Sandbox Code Playgroud)
我的配置有什么问题呢?
小智 0
肮脏但有效的解决方案:
用原则/迁移进行测试:3.0.1
我们可以修补 DiffGenerator 的模式删除功能。我个人用过这个https://github.com/cweagans/composer-patches
安装包,然后在composer.json“extra”部分添加:
"patches": {
"doctrine/migrations": {
"Change doctrine behavior to correctly pass PostgreSQL schema to schema_filter while diffing": "patches/doctrine-diff-generator.patch"
}
}
Run Code Online (Sandbox Code Playgroud)
补丁文件在patches/doctrine-diff-generator.patch中:
--- lib/Doctrine/Migrations/Generator/DiffGenerator.php 2020-06-21 10:55:42.000000000 +0200
+++ lib/Doctrine/Migrations/Generator/DiffGenerator.patched.php 2020-12-23 12:33:02.689405221 +0100
@@ -142,8 +142,6 @@
*/
private function resolveTableName(string $name) : string
{
- $pos = strpos($name, '.');
-
- return $pos === false ? $name : substr($name, $pos + 1);
+ return $name;
}
}
Run Code Online (Sandbox Code Playgroud)
当然,你必须记住,学说的更新可能会破坏补丁。并且您正在根据您的原则在全球范围内更改此功能,因此请注意重大更改。
就我个人而言,对于我的用例,将学说实体添加到遗留数据库中,而不破坏它,这工作得很好,并且使我免于将学说管理的每个新表添加到 schema_filter 中。
说明: 当我们研究 DiffGenerator 实现时,它实际上会正确解码具有模式的表名称,但仅在收集当前数据库模式时才有效。这发生在 PostgreSqlSchemaManager.php 中:
/**
* {@inheritdoc}
*/
protected function _getPortableTableDefinition($table)
{
$schemas = $this->getExistingSchemaSearchPaths();
$firstSchema = array_shift($schemas);
if ($table['schema_name'] === $firstSchema) {
return $table['table_name'];
}
return $table['schema_name'] . '.' . $table['table_name'];
}
Run Code Online (Sandbox Code Playgroud)
但是,当计算目标模式时,此信息会在 DiffGenerator.php 中丢失:
/**
* Resolve a table name from its fully qualified name. The `$name` argument
* comes from Doctrine\DBAL\Schema\Table#getName which can sometimes return
* a namespaced name with the form `{namespace}.{tableName}`. This extracts
* the table name from that.
*/
private function resolveTableName(string $name) : string
{
$pos = strpos($name, '.');
return $pos === false ? $name : substr($name, $pos + 1);
}
Run Code Online (Sandbox Code Playgroud)
然后该函数的返回值才会被传递到 schema_filter 中。不幸的是,但我想这是有原因的:)
| 归档时间: |
|
| 查看次数: |
1301 次 |
| 最近记录: |