Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 565
laycat Avatar asked Jul 10 '14 01:07

laycat


1 Answers

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, which includes this declared_attr example:

from sqlalchemy.ext.declarative import declared_attr

class ReferenceAddressMixin(object):
    @declared_attr
    def address_id(cls):
        return Column(Integer, ForeignKey('address.id'))

class User(ReferenceAddressMixin, Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True) ```
like image 161
davidism Avatar answered Oct 19 '22 06:10

davidism