So, I have a model that is something like:
class Foo(model):
__tablename__ = "foo"
id = Column(Integer, primary_key=True)
data = relationship(
"FooData",
cascade="all, delete-orphan",
backref="foo",
lazy="dynamic",
order_by="desc(FooData.timestamp)"
)
@property
def first_item(self):
# the problem is here:
return self.data.order_by(asc("timestamp")).first()
@property
def latest_item(self):
return self.data.first()
class FooData(Model):
__tablename__ = "foo_data"
foo_id = Column(Integer, ForeignKey("foo.id"), primary_key=True)
timestamp = Column(DateTime, primary_key=True)
actual_data = Column(Float, nullable=False)
So, the problem is with the first_item
method there: when it is defined as above, the SQL looks like this:
SELECT foo_data.timestamp AS foo_data_timestamp, foo_data.actual_data AS foo_data_actual_data, foo_data.foo_id AS foo_data_foo_id
FROM foo_data
WHERE :param_1 = foo_data.foo_id ORDER BY foo_data.timestamp DESC, foo_data.timestamp ASC
-- ^^^^^^^^^^^^^^^^^^^^^^
Obviously, the order_by
specified in the query is being appended to the one specified in the relationship definition, instead of replacing it; is there a way for a query to override the original order_by
? I know I could specify a separate query directly on the FooData
class, but I would like to avoid that if possible.
The comments class attribute defines a One-to-Many relationship between the Post model and the Comment model. You use the db. relationship() method, passing it the name of the comments model ( Comment in this case). You use the backref parameter to add a back reference that behaves like a column to the Comment model.
Lazy parameter determines how the related objects get loaded when querying through relationships. Below listed are the four main lazy parameters. Typically when you query the database, the data get loaded at once; however, lazy parameter allows you to alternate the way they get loaded. lazy = 'select' (or True)
primaryjoin – A SQL expression that will be used as the primary join of the child object against the parent object, or in a many-to-many relationship the join of the parent object to the association table.
In Flask-SQLAlchemy, the backref parameter in relationship method allows you to declare a new property under a specified class as seen in the example in their docs: class Person(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) addresses = db.relationship('Address', backref='person ...
According to documentation:
All existing ORDER BY settings can be suppressed by passing
None
- this will suppress any ORDER BY configured on mappers as well.
So the simple solution is to reset ORDER BY
clause and then apply the one you need. Like:
self.data.order_by(None).order_by(asc("timestamp")).first()
In case you don't want to reset whole ORDER BY
clause, but only want to override one column order, AFAIK there is no built-in way for it.
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