Flask-SQLAlchemy check if row exists in table

◇◆丶佛笑我妖孽 提交于 2019-12-17 15:43:37

问题


I have a Flask application which uses Flask-SQLAlchemy to connect to a MySQL database.

I would like to be able to check whether a row is present in a table. How would I modify a query like so to check the row exists:

db.session.query(User).filter_by(name='John Smith')

I found a solution on this question which uses SQLAlchemy but does not seem to fit with the way Flask-SQLAlchemy works:

from sqlalchemy.sql import exists    
print session.query(exists().where(User.email == '...')).scalar()

Thanks.


回答1:


Since you only want to see if the user exists, you don't want to query the entire object. Just query the id, it exists if the scalar return is not None.

exists = db.session.query(User.id).filter_by(name='davidism').scalar() is not None
SELECT user.id AS user_id 
FROM user 
WHERE user.name = ?

The second query you showed also works fine, Flask-SQLAlchemy does nothing to prevent any type of query that SQLAlchemy can make. This returns False or True instead of None or an id like above, but it is slightly more expensive because it uses a subquery.

exists = db.session.query(db.exists().where(User.name == 'davidism')).scalar()
SELECT EXISTS (SELECT * 
FROM user 
WHERE user.name = ?) AS anon_1



回答2:


Wrap a .exists() query in another session.query() with a scalar() call at the end. SQLAlchemy will produce an optimized EXISTS query that returns True or False.

exists = db.session.query(
    db.session.query(User).filter_by(name='John Smith').exists()
).scalar()
SELECT EXISTS (SELECT 1 
FROM user 
WHERE user.name = ?) AS anon_1

While it's potentially more expensive due to the subquery, it's more clear about what's being queried. It may also be preferable over db.exists().where(...) because it selects a constant instead of the full row.




回答3:


bool(User.query.filter_by(name='John Smith').first())

It will return "False" if objects with this name doesn't exist and "True" if it exist.




回答4:


Forgive the hijacking but ... with the instructions given here I made the following WTForm validator to check uniqueness of the field

class Unique(object):
    def __init__(self, column, session, message="Already exists."):
        self.column = column
        self.session = session
        self.message = message

    def __call__(self, form, field):
        if field.data == field.object_data:
            return  # Field value equals to existing value. That's ok.
        model = self.column.class_
        query = model.query.filter(self.column == field.data).exists()
        if self.session.query(query).scalar():
            raise ValidationError(self.message)

It would be used like this

class Register(Form):
    email = EmailField('Email', [Unique(User.email, db.session)])

However, I would like to have API which does not need db session as a second param

class Register(Form):
    email = EmailField('Email', [Unique(User.email)])

Is there any way to get db session from model? Without session it seems to be impossible to avoid loading the entire object to check its existence.




回答5:


Think there is a typo in davidism's answer, this works for me:

exists = db.session.query(**User**).filter_by(name='davidism').scalar() is not None


来源:https://stackoverflow.com/questions/32938475/flask-sqlalchemy-check-if-row-exists-in-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!