Skip to main content
Version: 6.4

常见问题

如何将数据库模式与实体同步?

¥How can I synchronize my database schema with the entities?

有两种方法:

¥There are two ways:

npx mikro-orm schema:update --run

我无法运行 CLI

¥I cannot run the CLI

确保在本地安装 @mikro-orm/cli 包。如果你想要全局安装,你也需要全局安装驱动程序包。

¥Make sure you install @mikro-orm/cli package locally. If you want to have global installation, you will need to install driver packages globally too.

EntityManager 没有 createQueryBuilder() 方法

¥EntityManager does not have createQueryBuilder() method

方法在那里,问题出在 TS 类型中。

¥The method is there, the issue is in the TS type.

在 v4 中,定义 EntityManagerEntityRepositorycore 包不依赖于 knex,因此它不能有返回 QueryBuilder 的方法。你需要从驱动程序包中导入 EM 的 SQL 风格才能访问 createQueryBuilder() 方法。

¥In v4 the core package, where EntityManager and EntityRepository are defined, is not dependent on knex, and therefore it cannot have a method returning a QueryBuilder. You need to import the SQL flavour of the EM from the driver package to access the createQueryBuilder() method.

EM 的 SQL 风格实际上称为 SqlEntityManager,它以这个名称和 EntityManager 别名导出,因此你只需更改导入的位置即可。

¥The SQL flavour of EM is actually called SqlEntityManager, it is exported both under this name and under EntityManager alias, so you can just change the location from where you import.

import { EntityManager } from '@mikro-orm/mysql'; // or any other SQL driver package

const em = orm.em as EntityManager;
const qb = await em.createQueryBuilder(...);

要使 orm.em 变量正确输入,你必须从驱动程序包中导入 MikroORM

¥To have the orm.em variable properly typed, you have to import the MikroORM from your driver package:

import { MikroORM } from '@mikro-orm/mysql'; // or any other SQL driver package

const orm = await MikroORM.init({
// ...
});
console.log(orm.em); // access EntityManager via `em` property

同样适用于 mongo 驱动程序中的 aggregate() 方法:

¥Same applies for the aggregate() method in mongo driver:

import { EntityManager } from '@mikro-orm/mongodb';

const em = orm.em as EntityManager;
const ret = await em.aggregate(...);

EM 的 mongo 风格实际上称为 MongoEntityManager,它以这个名称和 EntityManager 别名导出,因此你只需更改导入的位置即可。

¥The mongo flavour of EM is actually called MongoEntityManager, it is exported both under this name and under EntityManager alias, so you can just change the location from where you import.

如何将列添加到数据透视表(M:N 关系)

¥How can I add columns to pivot table (M:N relation)

你应该通过 1:m 和 m:1 属性透明地为你的 M:N 关系建模。有关此内容的更多信息,请参阅 复合键部分

¥You should model your M:N relation transparently, via 1:m and m:1 properties. More about this can be found in Composite Keys section.

你无法从生命周期钩子处理程序内部调用 em.flush()

¥You cannot call em.flush() from inside lifecycle hook handlers

即使你不使用钩子,也可能会看到此验证错误。如果发生这种情况,原因通常是因为你没有正确设置 请求上下文,并且你正在重复使用一个 EntityManager 实例。

¥You might see this validation error even if you do not use hooks. If that happens, the reason is usually because you do not have request context set up properly, and you are reusing one EntityManager instance.

正在使用 JSON 类型创建列,而 TS 类型为 string/Date/number/...

¥Column is being created with JSON type while the TS type is string/Date/number/...

你可能正在使用默认的 ReflectMetadataProvider,当存在属性初始化器时,它不支持推断属性类型。

¥You are probably using the default ReflectMetadataProvider, which does not support inferring property type when there is a property initializer.

@Property()
foo = 'abc';

有两种方法可以解决这个问题:

¥There are two ways around this:

@Property()
foo: string = 'abc';

如何通过原始 ID 设置外键?

¥How to set foreign key by raw id?

有几种方法:

¥There are several ways:

  1. 使用引用:

    ¥Using references:

const b = new Book();
b.author = em.getReference(Author, 1);
  1. 使用分配助手:

    ¥Using assign helper:

const b = new Book();
em.assign(b, { author: 1 });
  1. 使用创建助手:

    ¥Using create helper:

const b = em.create(Book, { author: 1 });

新实体实例初始化时所有属性均设置为 undefined

¥New entity instances get initialized with all properties set to undefined

使用 new Book()em.create(Book, {}) 创建新实体实例时,MikroORM 应返回:

¥When creating new entity instances, either with new Book() or em.create(Book, {}), MikroORM should return:

Book {}

但是有些用户可能会发现,这会返回一个具有明确设置为 undefined 的属性的对象:

¥But some users might find that this returns an object with properties that are explicitly set to undefined:

Book {
name: undefined,
author: undefined,
createdAt: undefined
}

这可能会导致意外行为,特别是如果你希望数据库为列设置默认值。

¥This can cause unexpected behavior, particularly if you're expecting the database to set a default value for a column.

要解决此问题,请在 tsconfig 中禁用 useDefineForClassFields 选项:

¥To fix this, disable the useDefineForClassFields option in your tsconfig:

{
"compilerOptions": {
"useDefineForClassFields": false
}
}

如何检查数据库连接是否有效?

¥How can I check if database connection works?

你可以使用两种方法来检查数据库状态,它们位于 Connection 类中,并且都在 MikroORM 类上有一个快捷方式:

¥There are two methods you can use to check the database status, they live on the Connection class and both have a shortcut on the MikroORM class too:

// boolean
const isConnected = await orm.isConnected();
// object with `ok`, `reason` and `error` keys
const check = await orm.checkConnection();

console.log(check.ok, check.reason);