我将Typeorm与类验证器结合使用,所以我定义了一个这样的实体:
import {
Entity,
PrimaryGeneratedColumn,
Column,
BaseEntity,
BeforeInsert,
BeforeUpdate,
getRepository
} from "typeorm";
import {
validateOrReject,
IsDefined,
} from "class-validator";
import errors from 'restify-errors';
@Entity()
export class License extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id!: string;
@Column({ nullable: false })
@IsDefined({ message: 'name field was not provided' })
public name!: string;
@Column({ nullable: false })
@IsDefined({ message: 'description field was not provided' })
public description!: string;
@BeforeInsert()
@BeforeUpdate()
async validate() {
await validateOrReject(this, { skipUndefinedProperties: true });
// Check if license already exists
if ((await getRepository(License).count({ name: this.name }) > 0))
throw new errors.BadRequestError(`There is already a license with name of ${this.name}`);
}
}
我还定义了一个中间件,它运行getMany
从Entity<T>
存储库中检索数据,例如:
export default (entity: any) => async (req: Request, res: Response, next: Next) => {
const repository = getRepository(entity);
const query = repository.createQueryBuilder(`${entity}`);
// Get query params
for (const propName in req.params) {
if (req.params.hasOwnProperty(propName)) {
query.where(`${propName} = :param`, { param: req.params[propName] });
}
}
// Pagination
const page = parseInt(req.query.page, 10) || 1;
const limit = parseInt(req.query.limit, 10) || 25;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const [result, total] = await query
.skip(startIndex)
.take(endIndex)
.getManyAndCount();
res.send({
"success": true,
"data": result,
"count": total,
"message": null
});
next();
};
当我运行中间件时,函数async validate()
也会被触发,但它不应该被触发,因为我得到的数据不是插入或更新它们。事实上,当触发validate
方法时,Typeorm
生成此错误:
"QueryFailedError:ER_PARSE_ERROR:您的SQL语法有错误;请查看与您的MySQL服务器版本相对应的手册,以获得正确的语法。'已经是名称为${this.name}
);rn });rn }rn}
的许可证。第12行的CCD_ 7A’;
如果我对函数validate
进行注释,则数据将正确地从中间件返回。
发生了什么事?这是图书馆的错误吗?
您的中间件似乎在查询中使用了以下消息:There is already a license with name of ${this.name}
。如果没有关于如何使用带有restify的中间件(server.use语句(的进一步指示,很难说这个错误消息负载是如何以及为什么会在中间件查询中结束的,但您应该朝着这个方向检查。
另一方面,如果您需要确保许可证名称的唯一性,您可能需要使用以下符号在name
上声明唯一密钥,而不是使用手动验证:
@Column({ nullable: false, unique: true })
public name!: string;
请在typeorm文档中找到更多信息:https://github.com/typeorm/typeorm/blob/master/docs/decorator-reference.md#column