2015-10-04 11 views
10

Flask-SQLAlchemyを使用してMySQLデータベースに接続するFlaskアプリケーションがあります。Flask-SQLAlchemyテーブルに行が存在するかどうかを調べる

テーブルに行があるかどうかを確認したいと考えています。その行をチェックするようにどのように私は、クエリを変更します存在:

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

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

私はSQLAlchemyのを使用していますが、フラスコSQLAlchemyの動作方法に適合していないようthis question上の解決策を見つけました

ありがとうございます。

+0

どのようにして、最初のクエリは、* *行が存在することを確認しないのですか? –

+0

行が存在する場合、クエリが 'True'または' False'を返すようにしたいと思います。 –

+0

2番目の方法で何が問題になっていますか? Flask-SQLAlchemyではうまく動作しますが、私はそれを試しました。 – davidism

答えて

16

ユーザーが存在するかどうかだけを確認したいので、オブジェクト全体を照会する必要はありません。 IDを照会するだけで、スカラー戻り値がNoneでない場合に存在します。

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

あなたが示した2番目のクエリでも正常に動作し、フラスコSQLAlchemyのはSQLAlchemyのを作ることができ、クエリのいずれかのタイプを防ぐために何もしません。

exists = db.session.query(db.exists().where(User.name == 'davidism')).scalar() 
8

終わりscalar()コールで別のsession.query().exists()クエリを包みます。

exists = db.session.query(
    db.session.query(User).filter_by(name='John Smith').exists() 
).scalar() 
+0

本当に 'User.id'を照会する必要があります。そうしないと、SQLAlchemyは必要以上に大きな照会を生成します。これは私の2番目の例と同じですが、 'db.exists'の代わりに' query.exists'を使うだけです。これは本質的に同じです。 – davidism

+0

@davidism SQLAlchemyはこれを 'SELECT EXISTS(SELECT 1 FROM user WHERE user.name =?)'に変換します。これは、 'SELECT user.id FROM user WHERE user.name =? 'よりも少し長いクエリですが、実際に質問されている質問をより正確に反映しています。同様に、Python側では、コードをユーザの検索によく似ているため、クエリを覚えやすく理解しやすくなります。 – lyschoening

+0

2つ存在すると、異なるクエリが生成されますか?興味深いことに、私はしばらくの間、そのような質問をしなかったことを確認しなければならないでしょう。 – davidism

0

は、ここに与えられた指示にハイジャックけど...を許して、私はそれがこの

class Register(Form): 
    email = EmailField('Email', [Unique(User.email, db.session)]) 
のように使用されるだろう
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) 

フィールドの一意性を確認するには、次のWTFormバリデータを作りました

しかし、2番目のパラメータとしてdbセッションを必要としないAPIを持っていたいです。

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

モデルからdbセッションを取得する方法はありますか?セッションがなければ、オブジェクトの存在を確認するためにオブジェクト全体をロードすることを避けることは不可能であるようです。

-2

が、これは私の作品、davidismの答えにタイプミスがあると思います。

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

これはtypoではありません。オブジェクト全体を取得することは、存在を確認することが難しいため、私は特にIDを照会しています。 – davidism

関連する問題