类的多个标识上的SQLAlchemy多态性

2024-04-19 02:34:39 发布

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

我尝试使用SQLAlchemy实现单表继承。 根据官方的SQLAlchemy文档(这里:official docs),分配单个多态标识的方法如下:

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity':'employee',
        'polymorphic_on':type
    }

我想为一个类分配多个标识。例如:

^{pr2}$

请注意以下行:

'polymorphic_identity': ['manager', 'ceo']

这条线是不可能的(不幸的)。在

我想知道是否有任何方法可以为一个类分配多个多态身份。 不幸的是,我在文档中找不到这样的例子。在


Tags: 方法文档docsstring官方sqlalchemytypeemployee
1条回答
网友
1楼 · 发布于 2024-04-19 02:34:39

因为类的polymorphic_identity被用作字典键,所以该代码无法工作。因此,与[] in {}引发TypeError的相同原因,您的代码也是如此。在

通常这样做的方法是创建一个CEO类,它是Manager的子类,然后它将能够拥有自己的polymorphic_identity以及{}。但除此之外,您可以为给定的类创建第二个polymorphic_identity(但这有点老套)。在

Base继承的每个类都引用相同的polymorphic_map,这只是一个dict

from sqlalchemy.orm import class_mapper
emp_mapper = class_mapper(Employee)
mgr_mapper = class_mapper(Manager)
print(type(emp_mapper.polymorphic_map))  # <class 'dict'>
print(emp_mapper.polymorphic_map is mgr_mapper.polymorphic_map)  # True

polymorphic_mappolymorphic_identity映射到Mapper,这样当从数据库中提取给定行时,可以使用指定为polymorphic_identity列的列的值来获取应该用来表示该数据的类。例如,在只定义了您的Employee类之后,polymorphic_map看起来像这样:{'employee': <Mapper at 0x1b1eafcac50; Employee>}。在将带有'manager'Manager类定义为polymorphic_identity之后,它看起来是这样的:{'employee': <Mapper at 0x25d10b19cf8; Employee>, 'manager': <Mapper at 0x25d0fdbd4e0; Manager>}

我将创建一些测试数据(我必须删除对公司表的所有引用-请参见MCVE):

^{pr2}$

现在,让我们把经理提升为CEO:

manager1.type = 'ceo'
s.commit()

这将发出警告:

SAWarning: Flushing object <Manager at 0x1e5e54a0cf8> with incompatible polymorphic identity 'ceo'; the object may not refresh and/or load correctly (this warning may be suppressed after 10 occurrences)

但我们将忽略这一点并尝试查询employee表:

print(s.query(Employee).all())

加薪:

Traceback (most recent call last):
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\sqlalchemy\orm\loading.py", line 721, in configure_subclass_mapper
    sub_mapper = mapper.polymorphic_map[discriminator]
KeyError: 'ceo'

因此manager1的type列现在有一个值,该值在polymorphic_map中不存在,我们得到一个键错误。因为我们只对CEO被表示为Manager感兴趣,所以我们只需手动将一个条目放入polymorphic_map中,将键'CEO'与Manager类的Mapper关联起来。E、 g组:

mgr_mapper.polymorphic_map['ceo'] = mgr_mapper

现在让我们再次查询employee表:

print(s.query(Employee).all())  #  [<__main__.Employee object at 0x0000020EE7320550>, <__main__.Manager object at 0x0000020EE7320CF8>, <__main__.Manager object at 0x0000020EE7320D68>]

现在再打印两个对象。在

免责声明:在ManagerMapper中,它维护了对类的polymorphic_identity的引用(即'manager'),因此,polymorphic_map中的{}键指向一个映射器,它引用了manager的{}。我之所以提到这一点,是因为在本例中,所有这些工作都很好,但我不知道这是否会导致sqlalchemy中其他地方的bug。所以,如果你在生产中使用这样的东西,确保它经过了良好的测试。在

相关问题 更多 >