Sequelize:同一个 table 中的多个实体中断测试
Sequelize: multiple entities in the same table breaks test
我继承了一个项目,其中 2 个续集实体存储在同一个 table 中。
所以他们都有相同的 tableName
和 schema
.
@Table({ tableName: 'thesametable', schema: 'schema', timestamps: false })
export default class FooModel extends Model<FooModel> {
fieldA: string
}
@Table({ tableName: 'thesametable', schema: 'schema', timestamps: false })
export default class BarModel extends Model<BarModel> {
fieldB: string
}
代码实际上运行良好,但是当我为此代码编写测试时,我使用了内存中的 SQL
dbConnection = new Sequelize('sqlite::memory:', {
models,
logging: false,
});
await dbConnection.sync({ force: true, logging: true });
jest.spyOn(FooModel, 'schema').mockImplementation(() => FooModel);
jest.spyOn(BarModel, 'schema').mockImplementation(() => BarModel);
到目前为止一切正常,但是当第一条记录插入 table 时,弹出错误。
DatabaseError [SequelizeDatabaseError]: SQLITE_ERROR: no such column: fieldB
检查日志文件后,我发现它只创建了一次 table,而且创建时,它只创建了第一个实体的字段。因此,当为第二个实体插入数据时,自然会缺少字段。
有没有办法告诉 sequelize/mysql 在创建 table 时有效地包含两个实体的字段。
我尝试了很多不同的设置。
- 我尝试将
force: true
更改为 alter: true
。
- 我尝试使用
define: { freezeTableNames: true }
- 我尝试添加
dialect: 'mysql'
- 我试过设置:
paranoid: true
因为它只影响测试,而且 table 中实际上有很多生产数据,更改 table 名称是我希望保留的最后一个选项。
编辑:
一段时间后,我意识到尽管这在生产中运行良好。代码 运行 为 2 个微服务,每个微服务仅使用 1 个实体。因此,虽然有 2 个实体使用相同的 table,但它们并不知道彼此的存在。然而,我的测试尝试使用所有模型。
所以你有两个同名的表?我相信 sync()
方法只会创建其中一个。除非您 运行 进行生产迁移以进行测试,否则我认为同步不会允许您拥有两个同名的表。
虽然有多个模型引用同一个 table,但我花了一些时间才意识到它们用于不同的微服务。因此,在实践中,它们从未一起使用过。这就解释了为什么在生产中没有问题。
我 运行 的测试也只需要访问一组有限的模型。
实际上可以明确说明它需要的那些。
dbConnection = new Sequelize('sqlite::memory:', {
models: [FooModel],
logging: false,
});
这一切都解决了。
我继承了一个项目,其中 2 个续集实体存储在同一个 table 中。
所以他们都有相同的 tableName
和 schema
.
@Table({ tableName: 'thesametable', schema: 'schema', timestamps: false })
export default class FooModel extends Model<FooModel> {
fieldA: string
}
@Table({ tableName: 'thesametable', schema: 'schema', timestamps: false })
export default class BarModel extends Model<BarModel> {
fieldB: string
}
代码实际上运行良好,但是当我为此代码编写测试时,我使用了内存中的 SQL
dbConnection = new Sequelize('sqlite::memory:', {
models,
logging: false,
});
await dbConnection.sync({ force: true, logging: true });
jest.spyOn(FooModel, 'schema').mockImplementation(() => FooModel);
jest.spyOn(BarModel, 'schema').mockImplementation(() => BarModel);
到目前为止一切正常,但是当第一条记录插入 table 时,弹出错误。
DatabaseError [SequelizeDatabaseError]: SQLITE_ERROR: no such column: fieldB
检查日志文件后,我发现它只创建了一次 table,而且创建时,它只创建了第一个实体的字段。因此,当为第二个实体插入数据时,自然会缺少字段。
有没有办法告诉 sequelize/mysql 在创建 table 时有效地包含两个实体的字段。
我尝试了很多不同的设置。
- 我尝试将
force: true
更改为alter: true
。 - 我尝试使用
define: { freezeTableNames: true }
- 我尝试添加
dialect: 'mysql'
- 我试过设置:
paranoid: true
因为它只影响测试,而且 table 中实际上有很多生产数据,更改 table 名称是我希望保留的最后一个选项。
编辑:
一段时间后,我意识到尽管这在生产中运行良好。代码 运行 为 2 个微服务,每个微服务仅使用 1 个实体。因此,虽然有 2 个实体使用相同的 table,但它们并不知道彼此的存在。然而,我的测试尝试使用所有模型。
所以你有两个同名的表?我相信 sync()
方法只会创建其中一个。除非您 运行 进行生产迁移以进行测试,否则我认为同步不会允许您拥有两个同名的表。
虽然有多个模型引用同一个 table,但我花了一些时间才意识到它们用于不同的微服务。因此,在实践中,它们从未一起使用过。这就解释了为什么在生产中没有问题。
我 运行 的测试也只需要访问一组有限的模型。 实际上可以明确说明它需要的那些。
dbConnection = new Sequelize('sqlite::memory:', {
models: [FooModel],
logging: false,
});
这一切都解决了。