Flask-SQLAlchemy检查表中是否存在行

时间:2015-10-04 21:14:37

标签: python flask sqlalchemy flask-sqlalchemy

我有一个Flask应用程序,它使用Flask-SQLAlchemy连接到MySQL数据库。

我希望能够检查表中是否存在行。我如何修改这样的查询以检查行是否存在:

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

我在this question上找到了一个使用SQLAlchemy的解决方案,但似乎不符合Flask-SQLAlchemy的工作方式:

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

感谢。

5 个答案:

答案 0 :(得分:32)

由于您只想查看用户是否存在,因此您不希望查询整个对象。只查询id,如果标量返回不是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 = ?

您展示的第二个查询也可以正常工作,Flask-SQLAlchemy不会阻止SQLAlchemy可以进行任何类型的查询。这会返回FalseTrue而非None或上面的ID,但稍微更昂贵,因为它使用子查询。

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

答案 1 :(得分:11)

在另一个.exists()中将session.query()个查询包裹在最后一个scalar()。 SQLAlchemy将生成一个返回EXISTSTrue的优化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

虽然由于子查询而可能更昂贵,但是查询的内容更清楚。它也可能优于db.exists().where(...),因为它选择一个常量而不是整行。

答案 2 :(得分:1)

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

如果不存在具有该名称的对象,则返回“ False”,如果存在则返回“ True”。

答案 3 :(得分:0)

原谅劫持但是...在这里给出的指示我做了以下WTForm验证器来检查该字段的唯一性

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)

它会像这样使用

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

但是,我希望API不需要db session作为第二个参数

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

有没有办法从模型中获取数据库会话?没有会话,似乎不可能避免加载整个对象来检查它的存在。

答案 4 :(得分:-2)

认为在大卫的答案中有一个错字,这对我有用:

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