如何为Doctrine 2.5与PostgreSQL 10配置默认Schema?
嘿,这个问题我之前在项目里也碰到过——Doctrine对于没有对应实体类的ManyToMany中间表,确实会默认丢去public schema里,不过有两个很实用的解决办法,咱们来聊聊:
你完全可以给Doctrine设置一个全局默认schema,这样所有实体表、包括自动生成的ManyToMany中间表都会默认使用这个schema,再也不用给每个实体类加@ORM\Table(schema="my-schema")注解了。
如果你用Symfony框架
修改config/packages/doctrine.yaml(旧版本是app/config/config.yml),在DBAL配置里加上default_schema:
doctrine: dbal: connections: default: driver: pdo_pgsql host: '%database_host%' port: '%database_port%' dbname: '%database_name%' user: '%database_user%' password: '%database_password%' charset: UTF8 default_schema: my-schema # 关键配置,指定默认schema orm: entity_managers: default: connection: default # 其他ORM配置...
如果你用纯Doctrine(无框架)
在创建EntityManager的时候,直接在DBAL参数里指定default_schema:
use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\EntityManager; $entityPaths = [__DIR__ . '/src/Entity']; $isDevMode = true; $dbParams = [ 'driver' => 'pdo_pgsql', 'user' => '你的数据库用户', 'password' => '你的数据库密码', 'dbname' => '你的数据库名', 'host' => 'localhost', 'port' => 5432, 'default_schema' => 'my-schema', // 全局默认schema ]; $config = Setup::createAnnotationMetadataConfiguration($entityPaths, $isDevMode); $entityManager = EntityManager::create($dbParams, $config);
配置完成后,你可以删掉所有实体类上的@ORM\Table(schema="my-schema")注解,Doctrine会自动把所有表(包括中间表)都建在my-schema里。
如果你不想全局修改默认schema,也可以在每个ManyToMany关联的注解里,手动给中间表指定schema:
/** * @ORM\Entity * @ORM\Table(schema="my-schema") */ class User { // ... /** * @ORM\ManyToMany(targetEntity="Role") * @ORM\JoinTable( * name="user_role", * schema="my-schema", // 给中间表指定schema * joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")} * ) */ private $roles; // ... }
这种方式适合你只想调整部分中间表的场景,但实体多的话,全局配置显然更高效。
配置完后,你可以用Doctrine的schema命令预览将要执行的SQL,确认中间表的schema是否正确:
# Symfony项目 php bin/console doctrine:schema:update --dump-sql # 纯Doctrine项目 ./vendor/bin/doctrine orm:schema-tool:update --dump-sql
输出的SQL里,中间表的创建语句应该会带上my-schema.前缀,而不是默认的public.。
另外别忘了确保你的数据库用户拥有my-schema的操作权限,不然可能会报错:
GRANT ALL ON SCHEMA my-schema TO 你的数据库用户;
内容的提问来源于stack exchange,提问作者Iván Pérez

