一、objectid生成问题,(meta的写法有问题,请参照二、约束的写法)
在使用mongoengine的时候,ORM映射字段中有id。这个时候会报错ValidationError。
先上结论:可以主动生成_id来解决这个问题。
_id是由4位时间戳+5位随机数+3位随机数递增计数器组成的12位十六进制字符。
我一开始的发现这个错误是mongoengine对id,_id处理都归类成_id的问题。
正常的使用原生mongo是可以有id字段的,mongoengine中将id和_id都划归了生成_id,所以当把id设置成主键之后,它可以正常运行,数据库中变成了_id字段,这明显与我们的需求不符合。mongoengine的queryset中 .id和 .pk 得到的就是_id的值
想要同时插入_id和id字段,就需要解决上面的问题,使用meta方法,可以同时插入两个字段,这个时候就需要解决_id的生成问题了。
使用mongoengine跟代码跟了很长时间,发现调用的位置之后,才恍然大悟,我可以直接查mongo的objectid生成规则就好了呀。
后来找了一下mongo的API文档。
二、objectid与唯一约束
先上正确写法
from config import config
from mongoengine import *
import datetime
# 两种都可以
from bson.objectid import ObjectId
# from bson import ObjectId
class Car(DynamicDocument):
_id = ObjectIdField(required=True,unique=True)
# # 第三种model 不建议使用下边这种
# _id = ObjectIdField(required=True,unique=True,default=ObjectId())
sources_name = StringField(required=True)
col = StringField(default='car')
created_at = DateTimeField(default=datetime.datetime.now)
meta = {
'collection': 'car',
'auto_create_index':False,
# 'id_field': '_id'
}
connect(**config.mongo_config)
# 插入
# 第一种
for i in range(5):
oid = ObjectId()
Car(**{'sources_name':str(i),'_id':oid}).save()
# 第二种
for i in range(5):
Car(**{'sources_name':str(i),'_id':ObjectId()}).save()
# 第三种 不建议写在model里,只会调用一次model生成一次objectid。
for i in range(5):
Car(**{'sources_name':str(i)}).save()
今天在给 _id加约束的时候报错。
查了很久,肯定是 _id的生成问题。
在追踪堆栈错误的时候看到这个,一想自己的 _id不是自动生成的啊。然后找了一下meta的用法。果然改成 {'auto_create_index':False,},唯一约束也可以使用了。
文档关于meta