I have simple entity
@Entity()
export class File {
@PrimaryGeneratedColumn()
id: number;
@Column({type: "mediumblob"})
data: Buffer;
}
Which I want to use on production with Mysql ("mediumblob" because I want to store 10MB files).
I also want to run integration tests but with sqlite
but it supports only "blob".
Then I want test like that:
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();
});
});
When I run such code I get error like this
DataTypeNotSupportedError: Data type "mediumblob" in "File.data" is not supported by "sqlite" database.
If I change column type to blob
then for mysql
I get following error when uploading 116kb
file
QueryFailedError: ER_DATA_TOO_LONG: Data too long for column 'data' at row 1
Is it somehow possible to generate some kind of logic/mapping to work arround incompatibility of mysql
/sqlite
so "blob"
is used for sqlite
while "mediumblob"
is used for mysql
?
TypeORM supports all type of database fields through Column class. Let us learn the different type of column supported by TypeORM in this chapter. @Column () decorator class is used to represent the column and its type in the entity.
Its attributes / member variables refer the corresponding database table’s fields / columns. TypeORM supports all type of database fields through Column class. Let us learn the different type of column supported by TypeORM in this chapter. @Column () decorator class is used to represent the column and its type in the entity.
Advanced relational database supports array datatype. To support the array datatype, TypeORM provides a special column type, *simple-array" to store primitive array values. A sample code to use it is as follows − Lot of modern database engine supports JSON database. To use JSON datatype, TypeORM provides a special type, single-json.
Similarly, TypeORM supports a different set of datatype for MySQL. TypeORM provides an extensive set of options other than type to describe the column. For example, length option refers the length of the database field and it can be specified as below −
We can create a simple decorator, @DbAwareColumn, on top of @Column. The new decorator corrects a column type based on environment. I expect you're using sqlite for the test environment
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);
}
In entities, we can use it as
@Entity({name: 'document'})
export class Document {
@DbAwareColumn({ name: 'body', type: 'mediumtext'})
body: string;
@DbAwareColumn({type: "mediumblob"})
data: Buffer;
@DbAwareColumn({type: "timestamp"})
createdAt: Date;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With