Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-SQLAlchemy .like() method raises NotImplementedError

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.

like image 859
ACV Avatar asked Sep 29 '22 10:09

ACV


1 Answers

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)
like image 184
ACV Avatar answered Oct 02 '22 16:10

ACV