laycat laycat - 7 months ago 20
Python Question

sqlalchemy, mixins, foreignkeys and declared_attr

I know that I need to @declared_attr when declaring columns with foreign keys on declarative mixin classes, however I would like to know the reason behind this.

thank you :)

#store traces
class ListContainer():
id = Column(Integer, primary_key=True)
# timestamp = Column(DateTime, default=datetime.now())
name = Column(String)
#endclass

#store flow in traces
def list_item(tablename):
class ListItem():
# @declared_attr
# def trace_id(cls):
# return Column(Integer, ForeignKey(tablename+'.id'))
trace_id = Column(Integer, ForeignKey(tablename+'.id'))
id = Column(Integer, primary_key=True)
item_pos = Column(Integer)
# start_ea = Column(BLOB)
# end_ea = Column(BLOB)
#endclass
return ListItem

Answer

Each model must have unique orm attributes. If the same attribute from a mixin was directly applied to each subclass, they would all have the same attribute. Copies of basic orm attributes are easy to create because they do not reference any other orm attributes. For more complex attributes, a function decorated with @declared_attr ensures that a new instance is created for each subclass.

During instrumentation, SQLAlchemy calls each declared attr for each class, assigning the result to the target name. In this way, it can ensure complex mapping happens uniquely and correctly for each subclass.

See the documentation.