1

我想拆分实体类的定义,即在我最初声明类之后(但在生成映射之前)添加列。这是可能吗?

我已将我的问题简化为下面的示例代码。它在映射的生成上抛出一个pony.orm.core.ERDiagramError: Reverse attribute for Passport.person not found。当我passport = Optional("Passport")输入类定义时,一切正常,但我想将护照部分与纯部分分开。

我知道答案可能只是:“对不起,戴夫。恐怕我做不到。”

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


from pony.orm import *


db = Database()

### PART 1: Person ###
class Person(db.Entity):
    id = PrimaryKey(int, auto=True)


### PART 2: Passport (belonging to a Person)  ###
Person.passport = Optional("Passport")

class Passport(db.Entity):
    person = Required("Person")


db.bind("sqlite", ":memory:")
db.generate_mapping(create_tables=True)
4

2 回答 2

1

我认为答案取决于用例。在您的评论中,您告诉您想要拥有应用程序的“基本”和“高级”版本。在这种情况下,我建议使用实体继承:

########## basic.py ##########
from pony.orm import *

db = Database()

class Person(db.Entity):
    name = Required(str)
    contacts = Set("Contact")
    classtype = Discriminator(str)

class Contact(db.Entity):
    person = Required(Person)
    type = Required(str)
    value = Required(str)

########## advanced.py ##########
from basic import *

class ExtendedPerson(Person):
    passport = Optional("Passport")

class Passport(db.Entity):
    person = Required(ExtendedPerson)
    code = Required(str, unique=True)

########## main.py ##########
from advanced import *
import settings

db.bind('postgres', **settings.db_params)
db.generate_mapping(create_tables=True)

with db_session:
    john = ExtendedPerson(name='John')
    p = Passport(person=john, code='123-456')

Discriminator列是用于继承的系统列。Pony 将所有子类存储在同一个表中,并根据该列的值确定特定实例的子类。通常 Pony 会自动添加此列,但如果您有时会导入basic模块,Pony 将不知道ExtendedPerson子类的存在,并且不会自动将该属性添加到实体定义中。

另一个用例是当您使用由另一个开发人员编写的第三方模块并希望扩展其功能时。对于这种情况,我们计划添加仅在一个实体中定义关系的可能性,稍后将对其进行定义。当我们添加这样的功能时,您将能够在Passport实体中定义一个关系,示例语法是:

类人(db.Entity):名称=必需(str)

class Passport(db.Entity):
    person = Required("Person",
        reverse='passport', reverse_attr=Optional("Passport"))
    code = Required(str, unique=True)

目前 Pony 没有这样的功能,但我们可以在不久的将来添加它

于 2016-12-16T13:08:12.393 回答
0

在浏览了 PonyORM 的源代码和一些试验和错误之后,我发现我可以做些什么来让它工作。虽然我不确定这是官方的,如果一切都需要。所以我不确定这在未来的版本中是否仍然有效。

编码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


from pony.orm import *


db = Database()

### PART 1: Person ###
class Person(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(unicode)


### PART 2: Passport (belonging to a Person)  ###
extra_column = Optional("Passport", reverse='person')
extra_column._init_(Person, 'passport')
Person._attrs_.append(extra_column)
Person._new_attrs_.append(extra_column)
Person._adict_['passport'] = extra_column
Person.passport = extra_column


class Passport(db.Entity):
    person = Required("Person", reverse='passport')


db.bind("sqlite", ":memory:")
db.generate_mapping(create_tables=True)
于 2016-12-15T22:30:46.777 回答