Search code examples
pythonsqlalchemyintrospection

SQLAlchemy relationship introspection


I have two mapped classes with a one-to-many relation:

class Part(...):
    product = relationship('products', backref=backref('parts'))

class Product(...):
    pass

Given Part.product, I can introspect this relationship, namely get the attribute name, and also get the backref attribute name:

>>> rel = Part.product   # image it's passed in as a function parameter
>>> rel.property.key
'product'
>>> rel.property.backref[0]
'parts'

I can also access the relationship the other way round:

>>> rel = Product.parts
>>> rel
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x3744fd0>
>>> rel.property.key
'parts'

However, I cannot find out how to access the original attribute name (aka the backref' backref attribute, aka 'product' in the example):

>>> rel.property.backref is None
True

Where do I have to tickle Product.parts to obtain 'product'?


Solution

  • I tried to reproduce situation your described and got Product.parts.property.backref = None too. After debugging in pycharm I found that other property holds the name of property in parts:

    print Product.parts.property.backref
    >>>None
    print Product.parts.property.back_populates
    >>>product
    

    I would suggest to consider using back_populates in this case as a hack.

    back_populates is described in documentation Linking Relationship Configuration:Relationships with Backref. According to documentation you would need to define your model like that:

    class Part(...):
        product = relationship('products', back_populates='parts')
    
    class Product(...):
        parts = relationship('products', back_populates='product')
        pass