一、objectid生成問題,(meta的寫法有問題,請參照二、約束的寫法)
在使用mongoengine的時候,ORM映射字段中有id。這個時候會報錯ValidationError。
先上結(jié)論:可以主動生成_id來解決這個問題。
_id是由4位時間戳+5位隨機(jī)數(shù)+3位隨機(jī)數(shù)遞增計數(shù)器組成的12位十六進(jìn)制字符。

id字段

image.png
我一開始的發(fā)現(xiàn)這個錯誤是mongoengine對id,_id處理都?xì)w類成_id的問題。
正常的使用原生mongo是可以有id字段的,mongoengine中將id和_id都劃歸了生成_id,所以當(dāng)把id設(shè)置成主鍵之后,它可以正常運行,數(shù)據(jù)庫中變成了_id字段,這明顯與我們的需求不符合。mongoengine的queryset中 .id和 .pk 得到的就是_id的值

image.png
想要同時插入_id和id字段,就需要解決上面的問題,使用meta方法,可以同時插入兩個字段,這個時候就需要解決_id的生成問題了。

image.png
使用mongoengine跟代碼跟了很長時間,發(fā)現(xiàn)調(diào)用的位置之后,才恍然大悟,我可以直接查mongo的objectid生成規(guī)則就好了呀。

image.png

image.png
后來找了一下mongo的API文檔。

調(diào)用生成objectid方法
二、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里,只會調(diào)用一次model生成一次objectid。
for i in range(5):
Car(**{'sources_name':str(i)}).save()
今天在給 _id加約束的時候報錯。

image.png
查了很久,肯定是 _id的生成問題。

image.png
在追蹤堆棧錯誤的時候看到這個,一想自己的 _id不是自動生成的啊。然后找了一下meta的用法。果然改成 {'auto_create_index':False,},唯一約束也可以使用了。
文檔關(guān)于meta