我有简单的实体
@Entity()
export class File {
@PrimaryGeneratedColumn()
id: number;
@Column({type: "mediumblob"})
data: Buffer;
}
我想在Mysql上使用它(" mediumblob"因为我想存储10MB文件)。
我还希望运行集成测试,但使用sqlite
但它只支持" blob"。
然后我想要那样测试:
describe("CR on File and blobs", () => {
it("should store arbitrary binary file", async (done) => {
const conn = await createConnection({
type: "sqlite",
database: ":memory:",
entities: ["src/models/file.ts"],
synchronize: true
});
const fileRepo = await conn.getRepository(File);
fileRepo.createQueryBuilder("file")
.where("file.id == :id", {id: 1})
.select([
"file.data"
])
.stream();
done();
});
});
当我运行这样的代码时,我得到这样的错误
DataTypeNotSupportedError: Data type "mediumblob" in "File.data" is not supported by "sqlite" database.
如果我将列类型更改为blob
,那么对于mysql
我在上传116kb
文件时会出现以下错误
QueryFailedError: ER_DATA_TOO_LONG: Data too long for column 'data' at row 1
是否有可能生成某种逻辑/映射来处理mysql
/ sqlite
的不兼容性,因此"blob"
用于sqlite
而"mediumblob"
}用于mysql
?
答案 0 :(得分:4)
我们可以在@Column顶部创建一个简单的装饰器@DbAwareColumn。新的装饰器会根据环境更正列类型。我希望您在 test 环境中使用sqlite
import { Column, ColumnOptions, ColumnType } from 'typeorm';
const mysqlSqliteTypeMapping: { [key: string]: ColumnType } = {
'mediumtext': 'text',
'timestamp': 'datetime',
'mediumblob': 'blob'
};
export function resolveDbType(mySqlType: ColumnType): ColumnType {
const isTestEnv = process.env.NODE_ENV === 'test';
if (isTestEnv && mySqlType in mysqlSqliteTypeMapping) {
return mysqlSqliteTypeMapping[mySqlType.toString()];
}
return mySqlType;
}
export function DbAwareColumn(columnOptions: ColumnOptions) {
if (columnOptions.type) {
columnOptions.type = resolveDbType(columnOptions.type);
}
return Column(columnOptions);
}
在实体中,我们可以将其用作
@Entity({name: 'document'})
export class Document {
@DbAwareColumn({ name: 'body', type: 'mediumtext'})
body: string;
@DbAwareColumn({type: "mediumblob"})
data: Buffer;
@DbAwareColumn({type: "timestamp"})
createdAt: Date;
}