【问题标题】:mongoengine NotUniqueError on empty collection空集合上的 mongoengine NotUniqueError
【发布时间】:2013-08-10 05:47:34
【问题描述】:

我正在尝试将第一个对象保存到集合中(我执行了 db.connection.drop_database() 以确保它是第一个对象),但我不断收到 *** NotUniqueError: Tried to save duplicate unique keys 错误。

这是我得到的一个简单示例:

ipdb> Card.objects.all()  
[]  
ipdb> card  
`<Card: <Card url/pk: c569e1c9-7311-441e-ba03-0e86d4bc2932>>`  
ipdb> card.save()  
*** NotUniqueError: Tried to save duplicate unique keys (E11000 duplicate key error index: contacts.dav_object.$username_1  dup key: { : null })  
ipdb> Card.drop_collection()  
ipdb> card.save()  
`<Card: <Card url/pk: c569e1c9-7311-441e-ba03-0e86d4bc2932>>`  
ipdb>

我正在使用 UnitTest,setUp 方法有 Card.ensure_indexes()。我怀疑它与它有关,但没有这一行 Mongo 将接受重复的条目,即使模型定义显示 unique=True。

如果我在Card.ensure_indexes() 之后添加Card._collection.drop_indexes(),这个问题就会消失,但是我会得到重复的条目,就像我上面说的那样。

这是卡片模型:

class Card(DavObject):  
    addressbook = db.ReferenceField("Addressbook")  
    url = db.StringField(required=True, unique=True, unique_with=["addressbook", "url"])  
    active = db.BooleanField(default=True)  
    text = db.StringField(required=True)  

这里是 DavObject:

class DavObject(db.Document):
    meta = {
        'allow_inheritance': True,
    }

    last_update = db.ComplexDateTimeField(required=True, default=datetime.utcnow)

    def __unicode__(self):
        return u"<%s url/pk: %s>" % (self.__class__.__name__, getattr(self, "url", self.pk))

    def save(self, *args, **kwargs):
        if self._get_changed_fields():
            self.last_update = datetime.utcnow()
        return db.Document.save(self, *args, **kwargs)

我不知道出了什么问题。

我正在使用 mongoengine 0.8.3、flask 0.10.1 和 python 2.7.3。

【问题讨论】:

  • 你能显示Card模型定义吗?
  • 更新了问题,有 Card 模型和它继承的模型。

标签: mongodb mongoengine


【解决方案1】:

看起来继承的问题:你为DavObject设置了'allow_inheritance': True,这意味着所有继承的模型都将存储在一个集合中。

对于从DavObject 继承的某些模型,您有username 索引,当您尝试插入两个从DavObject 继承的具有相同username 的文档时,它会发生冲突username(无)。

如果您不确定需要使用'allow_inheritance': True,而不是将其设置为False,或者尝试将具有不同索引的文档放在单独的集合中。

要检查我的假设,请尝试print list(DavObject.objects.all())。

【讨论】:

  • 是的,做到了!谢谢老兄,我在这个错误上已经超过 48 小时了。
  • 只需再添加一条信息,只需将'abstract': True 添加到DavObject meta 字典即可解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多