Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用flask mongoengine处理引用字段迁移?_Python_Mongoengine_Flask Admin_Flask Mongoengine - Fatal编程技术网

Python 如何使用flask mongoengine处理引用字段迁移?

Python 如何使用flask mongoengine处理引用字段迁移?,python,mongoengine,flask-admin,flask-mongoengine,Python,Mongoengine,Flask Admin,Flask Mongoengine,我用mongodb实现了一个简单的flask应用程序,现在需要一些升级 假设有一个Foo的类模型和一个Bar的类模型,其中有一个Foo的引用字段 class Foo(Document): title = StringField() class Bar(Document): name = StringField() foo = ReferenceField('Foo') 让flask应用程序运行一段时间,以便数据库中现在有一些数据 由于需求的变化,我们需要从一个新的超类重构Foo类

我用mongodb实现了一个简单的flask应用程序,现在需要一些升级

假设有一个Foo的类模型和一个Bar的类模型,其中有一个Foo的引用字段

class Foo(Document):
  title = StringField()

class Bar(Document):
  name = StringField()
  foo = ReferenceField('Foo')
让flask应用程序运行一段时间,以便数据库中现在有一些数据

由于需求的变化,我们需要从一个新的超类重构Foo类的子类:

class SuperFoo(Document):
  meta = { 'allow_inheritance': True,}
  #[...]

class Foo(SuperFoo):
  #[...]

class Bar(Document):
  name = StringField()
  foo = ReferenceField('Foo')

上面的代码在空数据库中运行良好

但如果其中有一些数据,当flask管理员试图显示Bar实例(在编辑模式下)时,mongoengine会引发异常

我认为数据模型需要以某种方式进行迁移

怎么做

谢谢,
亚历山德罗。

经过一番分析,我想出了解决问题的办法

Mongoengine创建了一个新的集合
super\u foo

每个继承类的文档都进入这个
super\u foo
集合,并带有一个附加属性
\u cls
。 该值是该类的CamelCased层次结构路径。在本例中,文档将具有

“u cls”:“SuperFoo.Foo”
字段

我所做的是将旧的
foo
集合中的每个文档复制到新的
super\u foo
one中,在每个文档中添加
{u cls':u'SuperPlesso.Plesso'}

迁移函数应该如下所示:

def migrationFunc():
    from pymongo.errors import DuplicateKeyError
    from my.app import models

    _cls = {'_cls': u'SuperFoo.Foo'}

    fromOldCollection = models.Foo._collection
    toSuperCollection = models.Superfoo._collection

    for doc in fromOldCollection.find():
        doc.update(_cls)
        try:
            toSuperCollection.insert(doc)
        except DuplicateKeyError:
            logger.error('...')
然后,我用实际的新层次结构更新了模型的基本代码:

class SuperFoo(Document):
  meta = { 'allow_inheritance': True,}
  #[...]

# was class Foo(Document)
class Foo(SuperFoo):
  #[...]
所有对
Bar
集合中或其他地方的
Foo
的反向引用都将保留

class SuperFoo(Document):
  meta = { 'allow_inheritance': True,}
  #[...]

# was class Foo(Document)
class Foo(SuperFoo):
  #[...]