【发布时间】:2022-01-06 19:36:08
【问题描述】:
我有一组作为纯 python 数据类起草的类。这是一个精简的示例,其行为与我预期的一样:
from dataclasses import dataclass
from abc import ABC
@dataclass
class Owner:
name: str = ""
@dataclass
class OwnedThing(ABC):
owner: Owner = None
@dataclass
class Thing1(OwnedThing):
name: str = ""
owner = Owner(name="foo")
thing = Thing1( name="bar", owner=owner)
print(thing.owner.name)
这里我们有一个基类,它确定许多派生类都将具有一个“所有者”对象。分配所有者很简单。
当我尝试添加 SqlAlchemy 以实现持久性时,我想保留一般继承结构,这样我就不必为所有各种拥有的事物重复这种所有者-事物关系。但是,当我这样做时,我不能再将所有者类实例分配给 .owner 属性:
from dataclasses import dataclass,field
from abc import ABC
from sqlalchemy.orm import declarative_mixin, declared_attr, relationship
from sqlalchemy import Column, ForeignKey
@dataclass
class Owner:
name: str = ""
@declarative_mixin
@dataclass
class OwnedThing(ABC):
owner_id: int = field(init=False, default=None)
owner: Owner = None
@declared_attr
def owner_id(cls):
return Column('owner_id', ForeignKey('owner.id'))
@declared_attr
def owner(cls):
return relationship(Owner)
@dataclass
class Thing1(OwnedThing):
name: str = ""
owner = Owner(name="foo")
thing = Thing1( name="bar", owner=owner)
print(thing.owner.name)
这将导致此堆栈跟踪:
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py:658: SAWarning: Unmanaged access of declarative attribute owner_id from non-mapped class OwnedThing
default = getattr(cls, a_name, MISSING)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py:658: SAWarning: Unmanaged access of declarative attribute owner from non-mapped class OwnedThing
default = getattr(cls, a_name, MISSING)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py:842: SAWarning: Unmanaged access of declarative attribute owner_id from non-mapped class OwnedThing
if isinstance(getattr(cls, f.name, None), Field):
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py:842: SAWarning: Unmanaged access of declarative attribute owner from non-mapped class OwnedThing
if isinstance(getattr(cls, f.name, None), Field):
Traceback (most recent call last):
File "test_case_sql.py", line 30, in <module>
thing = Thing1( name="bar", owner=owner)
File "<string>", line 2, in __init__
AttributeError: can't set attribute
请注意,当我跳过基类时,事情会按我的预期工作,没有错误:
from dataclasses import dataclass,field
from abc import ABC
from sqlalchemy.orm import declarative_mixin, declared_attr, relationship
from sqlalchemy import Column, ForeignKey,Integer
@dataclass
class Owner:
name: str = ""
@dataclass
class Thing1:
owner_id: int = Column(Integer)
owner: Owner = relationship("Owner")
name: str = ""
owner = Owner(name="foo")
thing = Thing1( name="bar", owner=owner)
print(thing.owner.name)
我对 SqlAlchemy 的内部结构了解得不够多,无法理解我做错了什么,而且我之前也没有看到其他人遇到过这个问题。有人可以帮我继续使用数据类和混合吗?
【问题讨论】:
标签: python sqlalchemy python-dataclasses