I am having trouble building a Flask-SQLAlchemy query with a like()
method, which should build a query using the the SQL LIKE
statement.
According the SQLAlchemy docs the like
method can be called on a column like this:
select([sometable]).where(sometable.c.column.like("%foobar%"))
I have a ModelClass that subclasses the Flask-SQLAlchemy db.Model
class. Defined like this:
class ModelClass(db.Model):
# Some other columns ...
field1 = db.Column(db.Integer(), db.ForeignKey('my_other_class.id'))
rel1 = db.relationship("MyOtherClass", foreign_keys=[field1])
I then have a loop where I am building up filters dynamically. Outside the loop I use these filters to filter a query. The inside of my loop, slightly modified, looks like this:
search_term = '%{}%'.format(search_string)
my_filter = getattr(ModelClass, field_string).like(search_term)
This raises an error at the line with the like
method:
NotImplementedError: <function like_op at 0x101c06668>
It raises this error for any text string. The Python docs for a NotImplementedError
say:
This exception is derived from RuntimeError. In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method.
This isn't an AttributeError
, so I think the like
method exists, but something else is wrong and I'm not sure what.
Update
Now that I'm looking more closely at the model definition I think the problem might be that I'm doing this on a relationship and not a Column
type.
I saw that type(getattr(ModelClass, field_string))
gives:
<sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x102018090>
Since this is not a Column
type I looked at the values for field_string
and saw that one of the values being passed was actually rel1
.
So I guess that's the "answer" but I'm still confused why calling .like()
on rel1
didn't raise an AttributeError
.
So I've confirmed the issue is that I was trying to apply the .like()
method to a relationship attribute instead of a column.
I changed my code to call the child model class directly as opposed to trying to go across the relationship from the parent to access the child class columns. Something like this:
search_term = '%{}%'.format(search_string)
my_filter = getattr(ChildModelClass, field_string).like(search_term)
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