MongoEngine ValidationError

时间:2014-12-17 09:14:05

标签: python mongodb flask mongoengine flask-mongoengine

我必须创建一个数据库,以及检查是否所有条目都在数据库中输入或不使用python shell。

我写了一个名为Trial

的课程
class Trial(db.Document):
    project_name = db.StringField(max_length=255,required=True)
    list_of_materials = db.ListField(db.EmbeddedDocumentField('List_Of_Materials'))
    abstract = db.StringField(max_length=255,required=True)
    vehicle = db.StringField(max_length=255,required=False)
    responsibilities = db.ListField(db.EmbeddedDocumentField('Responsibilities')) 

我定义了类List_of_Materials和责任如下:

class Responsibilities(db.EmbeddedDocument):
    employee = db.StringField(max_length=255, required = True)
    objective = db.StringField(max_length=255, required = True)

class List_Of_Materials(db.EmbeddedDocument):
    mat_name = db.StringField(max_length=255, required=True)
    mat_type = db.StringField()
    mat_comments = db.StringField(max_length = 255)

现在我使用python shell来输入数据库。

trial_test = Trial(project_name = 'nio field trip management',
                list_of_materials = [List_Of_Materials(mat_name = 'Laptop')],
                abstract = 'All is well that ends well',
                vehicle = Vehicle(veh_name='My Laptop',veh_num='GA07EX1234'),
                responsibilities = [Responsibilities(employee='Prashant',objective='Setup the Website')],

我收到以下错误:

Traceback (most recent call last):
  File "<stdin>", line 12, in <module>
  File "C:\Anaconda\lib\site-packages\mongoengine\base\document.py", line 85, in __init__
    value = field.to_python(value)
  File "C:\Anaconda\lib\site-packages\mongoengine\base\fields.py", line 261, in to_python
    self.error('You can only reference documents once they'
  File "C:\Anaconda\lib\site-packages\mongoengine\base\fields.py", line 124, in error
raise ValidationError(message, errors=errors, field_name=field_name)
mongoengine.errors.ValidationError: You can only reference documents once they have been saved to the database

代码的第12行是responsibilities=db.ListField(db.EmbeddedDocumentField('Responsibilities'))

我能从上述错误中解释的是,我们必须首先进入课程&#34;责任&#34;和&#34; List_Of_Material&#34; ,但是&#34; List_Of_Material&#34;在&#34;责任&#34;中没有出现任何错误。显示上述错误。

我该怎么做才能避免这个问题?

1 个答案:

答案 0 :(得分:3)

您确定发送的Trial型号是否合适?

当您在文档中声明一个ReferenceField时,抛出此ValidationError,并且在保存引用的文档之前尝试保存此文档(Mongoengine将MongoDB中的引用字段表示为包含引用的类和ObjectId的字典)

EmbeddedDocumentField不是ReferenceField。它们与主文档的保存时间相同。因此,我认为您的错误来自list_of_materialsresponsibilities属性。如果您在示例中删除了车辆分配,则此代码可以正常运行。

鉴于您的代码示例,我猜测有类似

的类
class Vehicle(db.Document):
    veh_name = db.StringField()
    veh_num = db.StringField()

你的模特是:

class Trial(db.Document):
    project_name = db.StringField(max_length=255, required=True)
    list_of_materials = db.ListField(db.EmbeddedDocumentField('List_Of_Materials'))
    abstract = db.StringField(max_length=255, required=True)
    vehicle = db.ReferenceField(Vehicle)
    responsibilities = db.ListField(db.EmbeddedDocumentField('Responsibilities'))

然后,你的例子应该是:

trial_test = Trial(
     project_name = 'nio field trip management',
     list_of_materials = [List_Of_Materials(mat_name = 'Laptop')],
     abstract = 'All is well that ends well',
     vehicle = Vehicle(veh_name='My Laptop',veh_num='GA07EX1234'),
     responsibilities = [Responsibilities(employee='Prashant',objective='Setup the Website')]
)
trial_test.vehicle.save()  # Saving the reference BEFORE saving the trial.
trial_test.save()