使用多个模式
在 MySQL 和 PostgreSQL 中,可以在多个模式中定义实体。在 MySQL 术语中,它被称为数据库,但从实现的角度来看,它是一个模式。
¥In MySQL and PostgreSQL it is possible to define your entities in multiple schemas. In MySQL terminology, it is called database, but from an implementation point of view, it is a schema.
要使用多个模式,你的连接需要能够访问所有模式(单个 MikroORM 实例不支持多个连接)。
¥To use multiple schemas, your connection needs to have access to all of them (multiple connections are not supported in a single MikroORM instance).
你需要做的就是通过 schema
选项定义模式名称,或者在 tableName
选项中包含模式名称的表名称:
¥All you need to do is simply define the schema name via schema
options, or table name including schema name in tableName
option:
@Entity({ schema: 'first_schema' })
export class Foo { ... }
// or alternatively we can specify it inside custom table name
@Entity({ tableName: 'second_schema.bar' })
export class Bar { ... }
然后照常使用这些实体。生成的 SQL 查询将使用此 tableName
值作为表名,因此只要你的连接可以访问给定的模式,一切都应该按预期工作。
¥Then use those entities as usual. Resulting SQL queries will use this tableName
value as a table name so as long as your connection has access to given schema, everything should work as expected.
你还可以通过 EntityManager
、EntityRepository
或 QueryBuilder
查询特定模式中的实体:
¥You can also query for entity in specific schema via EntityManager
, EntityRepository
or QueryBuilder
:
const user = await em.findOne(User, { ... }, { schema: 'client-123' });
要在特定模式中创建实体,你需要使用 QueryBuilder
:
¥To create entity in specific schema, you will need to use QueryBuilder
:
const qb = em.createQueryBuilder(User);
await qb.insert({ email: 'foo@bar.com' }).withSchema('client-123');
EntityManager
上的默认架构
¥Default schema on EntityManager
无需为每个实体或操作定义模式,可以使用 .fork()
EntityManger 并定义将与通配符模式一起使用的默认模式。
¥Instead of defining schema per entity or operation it's possible to .fork()
EntityManger and define a default schema that will be used with wildcard schemas.
const fork = em.fork({ schema: 'client-123' });
await fork.findOne(User, { ... });
// Will yield the same result as
const user = await em.findOne(User, { ... }, { schema: 'client-123' });
创建实体时,fork 将设置默认模式
¥When creating an entity the fork will set default schema
const fork = em.fork({ schema: 'client-123' });
const user = new User();
user.email = 'foo@bar.com';
await fork.persist(user).flush();
// Will yield the same result as
const qb = em.createQueryBuilder(User);
await qb.insert({ email: 'foo@bar.com' }).withSchema('client-123');
你还可以设置或清除模式
¥You can also set or clear schema
em.schema = 'client-123';
const fork = em.fork({ schema: 'client-1234' });
fork.schema = null;
EntityManager.schema
尊重上下文,因此如果在 请求上下文处理程序 内执行,全局 EM 将为你提供上下文模式
¥EntityManager.schema
Respects the context, so global EM will give you the contextual schema if executed inside request context handler
通配符模式
¥Wildcard Schema
自 v5 以来,我们可以等待 实例,它将自动执行 QB 并返回适当的响应。为此,我们只需指定通配符模式:
¥Since v5, MikroORM also supports defining entities that can exist in multiple schemas. To do that, we just specify wildcard schema:
@Entity({ schema: '*' })
export class Book {
@PrimaryKey()
id!: number;
@Property({ nullable: true })
name?: string;
@ManyToOne(() => Author, { nullable: true, deleteRule: 'cascade' })
author?: Author;
@ManyToOne(() => Book, { nullable: true })
basedOn?: Book;
}
使用 SchemaGenerator
时,默认情况下会忽略此类实体,因为我们需要指定要使用的架构。为此,我们需要使用 createSchema/updateSchema/dropSchema
方法的 schema
选项或 --schema
CLI 参数。
¥Entities like this will be by default ignored when using SchemaGenerator
, as we need to specify which schema to use. For that we need to use the schema
option of the createSchema/updateSchema/dropSchema
methods or the --schema
CLI parameter.
在运行时,通配符模式将被替换为 ORM 配置中的 FindOptions.schema
、EntityManager.schema
或 schema
选项。
¥On runtime, the wildcard schema will be replaced with either FindOptions.schema
, EntityManager.schema
or with the schema
option from the ORM config.
关于迁移的说明
¥Note about migrations
目前,迁移不支持此功能,它们将始终忽略通配符架构实体,并且需要明确使用 SchemaGenerator
。鉴于此类实体的动态特性,仅动态同步模式是有意义的,例如在 API 端点中。我们仍然可以使用 ORM 迁移,但我们需要手动将动态架构查询添加到迁移文件中。对于此类查询,使用 safe
模式是有意义的。
¥Currently, this is not supported via migrations, they will always ignore wildcard schema entities, and SchemaGenerator
needs to be used explicitly. Given the dynamic nature of such entities, it makes sense to only sync the schema dynamically, e.g. in an API endpoint. We could still use the ORM migrations, but we need to add the dynamic schema queries manually to migration files. It makes sense to use the safe
mode for such queries.