关于python:Flask-SQLAlchemy检查表中是否存在行

Flask-SQLAlchemy check if row exists in table

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

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

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

我找到了一个使用SQLAlchemy的问题的解决方案,但似乎不适合Flask-SQLAlchemy的工作方式:

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

谢谢。


由于您只想查看用户是否存在,因此您不想查询整个对象。只需查询id,如果标量返回不为None,它就存在。

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

您显示的第二个查询也可以正常工作,Flask-SQLAlchemy不会阻止SQLAlchemy进行任何类型的查询。这将返回FalseTrue而不是None或上面的id,但是由于使用了子查询,因此它的价格稍高一些。

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

.exists()查询包装在另一个session.query()中,并在末尾使用scalar()调用。 SQLAlchemy将生成优化的EXISTS查询,该查询返回TrueFalse

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

尽管由于子查询的原因,它的价格可能会更高,但对于要查询的内容却更加清楚。与db.exists().where(...)相比,它可能更可取,因为它选择一个常量而不是整行。


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

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


原谅劫持,但是……按照此处给出的说明,我制作了以下WTForm验证器来检查字段的唯一性

1
2
3
4
5
6
7
8
9
10
11
12
13
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)

它会像这样使用

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

但是,我想拥有不需要数据库会话作为第二个参数的API

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

有什么办法可以从模型中获取数据库会话?没有会话,似乎无法避免加载整个对象以检查其存在。


认为大卫的答案有错别字,这对我有用:

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