Sử dụng Python 3.5 và SQLAlchemy 1.0.14 (ORM).SQLAlchemy ORM: Thừa kế bảng đơn đa hình, với dự phòng cho lớp cha nếu không tìm thấy "polymorphic_identity"
Tôi có một bảng của nội dung kê khai như vậy:
from sqlalchemy.ext.declarative.api import declarative_base
Base = declarative_base()
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
type = Column(String)
# other non relevant attributes
My Items có thể có nhiều loại khác nhau, nhận dạng loại được lưu trữ trong type
. Đối với một vài loại đối tượng, tôi cần phải có các phương thức hoặc thuộc tính cụ thể có sẵn.
Để đạt được điều đó tôi cố gắng sử dụng thừa kế bảng duy nhất với một số SpecialisedItem như lớp con của Item:
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
type = Column(String, index=True)
# other non relevant attributes
__mapper_args__ = {
'polymorphic_on': type,
}
class SpecialisedItem(Base):
__mapper_args__ = {
'polymorphic_identity': 'specialitem',
}
def specialised_method(self):
return "I am special"
Bây giờ khi tôi tải các mặt hàng của tôi, tôi muốn tất cả các mục chuyên ngành (có type=='specialitem'
) để được nạp như vậy, trong khi bất kỳ giá trị kiểu nào khác sẽ dẫn đến lớp cha mẹ Item
đang được tải. Điều đó không hiệu quả, tôi nhận được AssertionError: No such polymorphic_identity 'normal' is defined
khi tải các mục.
Tôi muốn tránh tạo các lớp thừa kế không làm gì để trang trải tất cả các giá trị type
có thể có, thay vì có "chưa được ánh xạ" type
quay trở lại lớp cha Item
.
Có cách nào để đạt được hiệu ứng đó không?
trường hợp thử nghiệm tối thiểu để tham khảo:
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.sql.schema import Column
from sqlalchemy.sql.sqltypes import Integer, String
Base = declarative_base()
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
type = Column(String, index=True)
# other non relevant attributes
__mapper_args__ = {
'polymorphic_on': type,
}
class SpecialisedItem(Item):
__mapper_args__ = {
'polymorphic_identity': 'special',
}
specialAttribute = Column(String)
def specialised_method(self):
return "I am special"
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
session.add(Item(type='normal'))
session.add(Item(type='special'))
session.commit()
# loading only specialized items works
for item in session.query(Item).filter_by(type="special"):
print(item.specialised_method())
# loading other items fails
for item in session.query(Item):
print(item.type)
Cảm ơn,
Guillaume
Điều đó hoạt động, cảm ơn! Nếu bạn không phiền, tôi đã cập nhật mã phản hồi của bạn để hoạt động trực tiếp. Bạn sẽ nhận được phần thưởng. – Guillaume