Flask-SQLAlchemy check if row exists in table

前端 未结 5 2032
耶瑟儿~
耶瑟儿~ 2020-12-05 02:17

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 woul

相关标签:
5条回答
  • 2020-12-05 02:34

    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
    
    0 讨论(0)
  • 2020-12-05 02:48

    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
    
    0 讨论(0)
  • 2020-12-05 02:56

    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.

    0 讨论(0)
  • 2020-12-05 02:57

    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.

    0 讨论(0)
  • 2020-12-05 02:58
    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 exists.

    0 讨论(0)
提交回复
热议问题