How to initialize backrefs of mappers without some queries through a session? For example, I have two models, named "Client" and "Subject" in follow code:
Base = declarative_base()
class Client(Base):
__tablename__ = "clients"
id = Column(Integer, primary_key=True)
created = Column(DateTime, default=datetime.datetime.now)
name = Column(String)
subjects = relationship("Subject", cascade="all,delete",
backref=backref("client"))
class Subject(Base):
__tablename__ = "subjects"
id = Column(Integer, primary_key=True)
client_id = Column(Integer, ForeignKey(Client.id, ondelete='CASCADE'))
Then, somewhere in my code, I want to get the backref client
of the class Subject
like this, but that raises an exception:
>>> Subject.client
AttributeError: type object 'Subject' has no attribute 'client'
After a query to Client
like:
>>> session.query(Client).first()
>>> Subject.client
<sqlalchemy.orm.attributes.InstrumentedAttribute at 0x43ca1d0>
Attribute client
was created after a query to the related model(mapper).
I don't want to make such "warming" queries!
Using backref just automates the creation of a relationship property at the other end. backref='person' is somewhat akin to having person = db. relationship('Person') explicitly in the Address class (+ back population). Using the backref() object you can pass arguments to that relationship.
Learn about Klaviyo's back-populate feature which allows you to queue people for flow actions retroactively. This is useful when you create a new flow, as back-populating allows you to populate contacts into your flow that would have been queued in real-time had the flow existed earlier.
Alternatively, you could use:
from sqlalchemy.orm import configure_mappers
configure_mappers()
This has the advantage that it creates all the backrefs for all your models in one step.
Because SQLAlchemy uses metaclasses, the code that creates the back reference on the other class won't run until you have created at least one instance of the Client
class.
The remedy is simple: create a Client()
instance, and discard it again:
>>> Subject.client
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Subject' has no attribute 'client'
>>> Client()
<__main__.Client object at 0x104bdc690>
>>> Subject.client
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x104be9e10>
or use the configure_mappers
utility function:
from sqlalchemy.orm import configure_mappers
to scan your models for such references and initialize them. Creating any one instance calls this method under the hood, actually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With