查看帖子的底部,您可以看到我有三个班级。这里的代码是动态编写的伪代码,未经测试,但它充分显示了我的问题。如果我们需要实际的课程,我可以在明天上班时更新这个问题。因此,请忽略仅代表思想的语法问题和代码,而不是那些我将在那里描述的实际“代码”。
问题1 如果查看Item搜索类方法,您可以看到当用户进行搜索时,我在基类上调用搜索,然后根据该结果返回正确的类/对象。这有效,但看起来很笨拙。有更好的方法吗?
问题2 如果您查看KitItem类,您可以看到我覆盖了定价。如果标志calc_list设置为true,那么我将组件的清单价格相加并将其作为套件的清单价格返回。如果未标记为true,我想返回“基本”清单价格。但是据我所知,没有办法访问父属性,因为在正常设置中它没有意义,但是使用sqlalchemy和共享表继承它可能很有用。
TIA
class Item(DeclarativeBase):
__tablename__ = 'items'
item_id = Column(Integer,primary_key=True,autoincrement=True)
sku = Column(Unicode(50),nullable=False,unique=True)
list_price = Column(Float)
cost_price = Column(Float)
item_type = Column(Unicode(1))
__mapper_args__ = {'polymorphic_on': item_type}
__
def __init__(self,sku,list_price,cost_price):
self.sku = sku
self.list_price = list_price
self.cost_price = cost_price
@classmethod
def search(cls):
"""
" search based on sku, description, long description
" return item as proper class
"""
item = DBSession.query(cls).filter(...) #do search stuff here
if item.item_type == 'K': #Better way to do this???
return DBSession.query(KitItem).get(item.item_id)
class KitItem(Item):
__mapper_args__ = {'polymorphic_identity': 'K'}
calc_list = Column(Boolean,nullable=False,default=False)
@property
def list_price(self):
if self.calc_list:
list_price = 0.0
for comp in self.components:
list_price += comp.component.list_price * comp.qty
return list_price
else:
#need help here
item = DBSession.query(Item).get(self.item_id)
return item.list_price
class KitComponent(DeclarativeBase):
__tablename__ = "kit_components"
kit_id = Column(Integer,ForeignKey('items.item_id'),primarykey=True)
component_id = Column(Integer,ForeignKey('items.item_id'),primarykey=True)
qty = Column(Integer,nullable=False, default=1)
kit = relation(KitItem,backref=backref("components"))
component = relation(Item)
答案 0 :(得分:1)
答案1:实际上你不需要在这里做任何特别的事情:假设你正确配置了继承层次结构,你的查询就会为每一行返回正确的类({{1} }或Item
)。这是ORM部分的优势。您可以做的是将查询配置为立即加载属于KitItem
子项的其他列(来自您的代码,这只是Item
列),您可以通过指定{ {1}}:
calc_list
在Basic Control of Which Tables are Queried中详细了解这一点
要查看差异,启用SQL日志记录,并在使用和不使用with_polymorphic('*')
时比较测试脚本 - 您很可能需要执行较少的@classmethod
def search(cls):
item = DBSession.query(cls).with_polymorphic('*').filter(...) #do search stuff here
return item
语句。
答案2:我不会覆盖一个归属于纯粹计算的条目。相反,我只是创建另一个计算属性(让我们称之为with_polymorphic(...)
),对于两个类中的每一个,它们看起来都是如下:
SQL
同样在这种情况下,您可能会考虑将关系final_price
配置为急切加载,以便class Item(Base):
...
@property
def total_price(self):
return self.list_price
class KitItem(Item):
...
@property
def total_price(self):
if self.calc_list:
_price = 0.0
for comp in self.components:
_price += comp.component.list_price * comp.qty
return _price
else:
# @note: again, you do not need to perform any query here at all, as *self* is that you need
return self.list_price
的计算不会触发其他SQL。但是你必须自己决定这对你的用例是否有益(再次,分析你的场景中生成的SQL)。