Python DDD模型中的递归关系

2024-09-29 17:11:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在琢磨如何在Python DDD模型中表示公司组织结构图,即没有外部依赖关系的纯域模型

我找到了这篇关于Java的文章,但我找不到如何在Python中做到这一点 How to model recursive relationships in DDD

与上面的链接一样,根类组织具有OrganizationUnit,可以具有任意嵌套深度的分区和子分区

数据持久化是通过数据库的SQLAlchemy实现的,它使用了一个经典映射(官方名称为命令映射,来自于2021年3月15日发布的SQLAlchemy 1.4)

###################
# domain/model.py

Class OrganizationalUnit:
    def __init__(
        self,
        parent_org_unit: "OrganizationalUnit",
        name,
    ):
        self.parent_org_unit = parent_org_unit
        self.name = name


###################
# adapters/orm.py
# code still uses classical syntax (no imperative mapping yet)


tb_organizational_unit = Table(
    "tb_organizational_unit",
    metadata,
    Column(
       "pk_organizational_unit", UUID(as_uuid=True), unique=True, nullable=False
    ),
    Column(
        "fk_parent_organizational_unit", UUID(as_uuid=True), ForeignKey(tb_organizational_unit.pk_organizational_unit),
    ),
    Column("name", String(255)),
)

    organizational_unit_mapper = mapper(
        domain.model.OrganizationalUnit,
        tb_organizational_unit,
        properties={
            "parent_organization_unit": relationship(
                domain.model.OrganizationalUnit, foreign_keys=[tb_organizational_unit.c.fk_parent_organizational_unit]
            ),
        },
    )

###################
# tests/adapters/test_orm.py

def test_organizational_unit_mapper_can_add():
    org_1 = model.OrganizationalUnit(
        parent_org_unit=None,
        name="Finance"
    )
    org_2 = model.OrganizationalUnit(
        client=client,
        parent_org_unit=org_1,
        name="Accounting",
    )
    session.add(org_2)
    session.commit()
    result = list(session.execute("SELECT name FROM tb_organizational_unit"))[0][0]
    assert result == ("Accounting")

 

但是运行测试会从这行适配器/orm.py返回一个错误:

"fk_parent_organizational_unit", UUID(as_uuid=True), ForeignKey(tb_organizational_unit.pk_organizational_unit) -> NameError: name 'tb_organizational_unit' is not defined

这似乎合乎逻辑,因为我在自己的定义中使用了tb_组织单位

如何在Python中解析这种递归数据结构


Tags: namepyorgselftruemodeldomainorm
1条回答
网友
1楼 · 发布于 2024-09-29 17:11:00

我可以通过区分SQLAlchemy表对象名称(前缀为“table_u2;”)和SQL表名称(前缀为“tb_2;”)来解决我的问题:

###################
# adapters/orm.py
# code still uses classical syntax (no imperative mapping yet)


table_organizational_unit = Table(
    "tb_organizational_unit",
    metadata,
    Column(
       "pk_organizational_unit",
       UUID(as_uuid=True),
       unique=True,
       nullable=False
    ),
    Column(
        "fk_parent_organizational_unit",
        UUID(as_uuid=True), 
        ForeignKey("tb_organizational_unit.pk_organizational_unit"),
    ),
    Column("name", String(255)),
)

    organizational_unit_mapper = mapper(
        domain.model.OrganizationalUnit,
        table_organizational_unit,
        properties={
            "parent_organizational_unit": relationship(
                domain.model.OrganizationalUnit,              
                foreign_keys=[table_organizational_unit.c.fk_parent_organizational_unit]
            ),
        },
    )

###################
# tests/adapters/test_orm.py

def test_organizational_unit_mapper_can_add():
    org_1 = model.OrganizationalUnit(
        parent_org_unit=None,
        name="Finance"
    )
    org_2 = model.OrganizationalUnit(
        client=client,
        parent_org_unit=org_1,
        name="Accounting",
    )
    session.add(org_2)
    session.commit()
    result = list(session.execute("SELECT name FROM tb_organizational_unit"))[1][0]
    assert result == ("Accounting")

相关问题 更多 >

    热门问题