2

How to apply a customized filter in sqlalchemy? I have tried @hybrid_property and @hybrid_method. However, they are giving errors. Here is my code:

class Product(db.Model):
    __tablename__ = 'products'
    id = db.Column(db.Integer, primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    keywords  = db.Column(db.String(64)) # keywords for ease of browsing
    details = db.Column(db.Text)
    removed = db.Column(db.Boolean, default=False)
    @hybrid_method
    def toKeywordLevenshteinDistance(self, keywords):
        """
        :param user input product keywords
        :return Levenshtein(user_input_keywords, product_keywords)
        """
        return fuzz.partial_ratio(self.keywords, keywords)
    
    @toKeywordLevenshteinDistance.expression
    def toKeywordLevenshteinDistance(cls, keywords):
        return func.fuzz.partial_ratio(cls.keywords, keywords)

>>> p=similarProducts('jrjk')

Here is the output:

File "C:\Users\AllWatt\App\flask\myStoreEnv\lib\site-packages\sqlalchemy\engine\default.py", 
line 608, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such function: levenshtein
    [SQL: SELECT products.id AS products_id, products.owner_id AS products_owner_id, 
    products.keywords AS products_keywords, products.details AS products_details,
    products.removed AS products_removed, products."when" AS products_when FROM products
    WHERE levenshtein(products.keywords, ?) > ?] [parameters: ('jrjk', 20)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
3
  • (sqlite3.OperationalError) no such function: levenshtein I guess that means it's still trying to call your function inside sqllite Commented Jun 27, 2021 at 3:00
  • What is similarProducts ? Commented Jun 27, 2021 at 3:01
  • @Z4-tier, it's a function which retrieve all the products with Levenshtein_distance(Product.keywords , given _keywords)>20 Commented Jun 27, 2021 at 3:39

1 Answer 1

2

You can use an event listener to register custom functions with sqlite on connection. Here's a simple example:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import sqlalchemy as sa

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'

db = SQLAlchemy(app)


def doubleit(word):
    return word * 2


@sa.event.listens_for(db.engine, 'connect')
def on_connect(dbapi_connection, connection_record):
    dbapi_connection.create_function('doubleit', 1, doubleit)


@app.route('/<word>')
def word_doubler(word):
    result = db.session.query(sa.func.doubleit(word))
    return result.scalar()


if __name__ == '__main__':
    app.run(debug=True)

Related docs:

Sign up to request clarification or add additional context in comments.

1 Comment

I'm using an application factory for my Flask app, so I needed to move the def on_connect... block inside my create_app() function, and I also needed to define it within an app context like with app.app_context(): @sa.event...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.