SQLAlchemy ORMチュートリアルの2:Query

8910 ワード

SQLAlchemyチュートリアルシリーズインデックス
  • SQLAlchemy ORMチュートリアルの1つ:Create
  • SQLAlchemy ORMチュートリアルの2:Query(本)
  • SQLAlchemy ORMチュートリアルの3:Relationship
  • SQLAlchemy ORMチュートリアルの1つであるCreateに続く2番目のチュートリアルです.前回では、ORMシステムの構成方法、クラスからテーブルへのマッピングの確立方法、レコードの挿入と変更方法について説明しました.このチュートリアルでは、主に使用する問題を解決します.
    Query Sessionquery関数は、Queryオブジェクトを返します.query関数は、複数のパラメータタイプを受け入れることができる.クラス、またはクラスのinstrumented descriptorです.次の例では、Userの記録をすべて取り出した.
    >>> for instance in session.query(User).order_by(User.id):
    ...     print(instance.name, instance.fullname)
    ed Ed Jones
    wendy Wendy Williams
    mary Mary Contrary
    fred Fred Flinstone
    
    Queryはまた、パラメータとしてORM-instrumented descriptorsを受け入れる.複数のパラメータが入力されると、同じ順序で返されるtuples
    >>> for name, fullname in session.query(User.name, User.fullname):
    ...     print(name, fullname)
    ed Ed Jones
    wendy Wendy Williams
    mary Mary Contrary
    fred Fred Flinstone
    
    Queryによって返されるtuplesは、KeyedTupleというクラスによって提供され、そのメンバーは、下付きアクセス以外にもインスタンス変数として取得することができる.対応する変数の名前は、クエリーされたクラス変数の名前と同じです.次の例を示します.
    >>> for row in session.query(User, User.name).all():
    ...    print(row.User, row.name)
     ed
     wendy
     mary
     fred
    
    label()でdescriptor対応インスタンス変数の名前を作成できます
    >>> for row in session.query(User.name.label('name_label')).all():
    ...    print(row.name_label)
    ed
    wendy
    mary
    fred
    

    クラスパラメータの場合、同じカスタマイズを実現するにはaliasedを使用する必要があります.
    >>> from sqlalchemy.orm import aliased
    >>> user_alias = aliased(User, name='user_alias')
    
    SQL>>> for row in session.query(user_alias, user_alias.name).all():
    ...    print(row.user_alias)
    
    
    
    
    

    基本的なクエリー操作には、上記のほかにOFFSETとLIMITが含まれており、これはPythonのarray sliceで行うことができます.
    >>> for u in session.query(User).order_by(User.id)[1:3]:
    ...    print(u)
    
    
    

    上記のプロセスは、実際には、フィルタリングを行わずに全体的な取り出し操作にのみ関与し、フィルタリングによく用いられる関数はfilter_byおよびfilterである.後者は前者よりも柔軟で、後者のパラメータでpythonの演算子を使用できます.
    >>> for name, in session.query(User.name).\
    ...             filter_by(fullname='Ed Jones'):
    ...    print(name)
    ed
    >>> for name, in session.query(User.name).\
    ...             filter(User.fullname=='Ed Jones'):
    ...    print(name)
    ed
    
    Queryオブジェクトはgenerativeであることに注意してください.これは、次のように直列に呼び出すことができます.
    >>> for user in session.query(User).\
    ...          filter(User.name=='ed').\
    ...          filter(User.fullname=='Ed Jones'):
    ...    print(user)
    
    

    連結されたfilterの間には、との関係がある.
    よく使用されるfilterオペレータ
    次のオペレータはfilter関数に適用できます.
  • equals :
  • query.filter(User.name == 'ed')
    
  • not equals :
  • query.filter(User.name != 'ed')
    
  • LIKE :
  • query.filter(User.name.like('%ed%'))
    
  • IN :
  • query.filter(User.name.in_(['ed', 'wendy', 'jack']))
    
    # works with query objects too:
    query.filter(User.name.in_(
            session.query(User.name).filter(User.name.like('%ed%'))
    ))
    
  • NOT IN :
  • query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
    
  • IS NULL :
  • query.filter(User.name == None)
    
    # alternatively, if pep8/linters are a concern
    query.filter(User.name.is_(None))
    
  • IS NOT NULL :
  • query.filter(User.name != None)
    
    # alternatively, if pep8/linters are a concern
    query.filter(User.name.isnot(None))
    
  • AND :
  • # use and_()
    from sqlalchemy import and_
    query.filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))
    
    # or send multiple expressions to .filter()
    query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
    
    # or chain multiple filter()/filter_by() calls
    query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
    
  • OR :
  • from sqlalchemy import or_
    query.filter(or_(User.name == 'ed', User.name == 'wendy'))
    
  • MATCH :
  • query.filter(User.name.match('wendy'))
    

    リスト(List)と単項(Scalar)を返す
    多くのQueryの方法でSQLコマンドが実行され、取り出されたデータベースの結果が返されます.
  • all()はリストを返します:
  • >>> query = session.query(User).filter(User.name.like('%ed')).order_by(User.id)
    SQL>>> query.all()
    [,
          ]
    
  • first()は、複数の結果を返し、1つの要素のみのtupleの形式ではなく、単項の形式でこの結果を返す.
  • >>> query.first()
    
    
  • one()は、クエリ結果を1つだけ返します.結果の数が1つ以上足りない場合は、エラーが発生します.
  • >>> user = query.one()
    Traceback (most recent call last):
    ...
    MultipleResultsFound: Multiple rows were found for one()
    

    結果が見つからない場合:
    >>> user = query.filter(User.id == 99).one()
    Traceback (most recent call last):
    ...
    NoResultFound: No row was found for one()
    
  • one_or_none():名前から分かるように、結果の数が0の場合、Noneを返し、1つの時報エラー
  • より多い.
  • scalar()one()は類似しているが、tuple
  • ではなく単項を返す.
    埋め込み使用SQLQueryでは、text()でSQL文を使用できます.例:
    >>> from sqlalchemy import text
    >>> for user in session.query(User).\
    ...             filter(text("id<224")).\
    ...             order_by(text("id")).all():
    ...     print(user.name)
    ed
    wendy
    mary
    fred
    

    パラメータを文字列に直接書き込む方法に加えて、params()方法でパラメータを渡すこともできます.
    >>> session.query(User).filter(text("id<:value and="" name=":name")).\" ...="" params="" fullname="Fred Flinstone" password="blah">
    

    また、完全なSQL文を直接使用できますが、テーブル名とカラムを正しく書くことに注意してください.
    >>> session.query(User).from_statement(
    ...                     text("SELECT * FROM users where name=:name")).\
    ...                     params(name='ed').all()
    []
    

    カウントQueryは便利なカウント関数count()を定義した.
    >>> session.query(User).filter(User.name.like('%ed')).count()
    SELECT count(*) AS count_1
    FROM (SELECT users.id AS users_id,
                    users.name AS users_name,
                    users.fullname AS users_fullname,
                    users.password AS users_password
    FROM users
    WHERE users.name LIKE ?) AS anon_1
    ('%ed',)
    2
    

    実際のSQLコマンドも同時にリストされていることに注意してください.SQLAlchemyでは、カウントされたクエリーを常にサブクエリーにパッケージ化し、このサブクエリーをカウントします.最も簡単なSELECT count(*) FROM tableでも、このように処理されます.より詳細な制御カウントプロセスのために,func.count()という関数を用いることができる.
    >>> from sqlalchemy import func
    SQL>>> session.query(func.count(User.name), User.name).group_by(User.name).all()
    SELECT count(users.name) AS count_1, users.name AS users_name
    FROM users GROUP BY users.name
    ()
    [(1, u'ed'), (1, u'fred'), (1, u'mary'), (1, u'wendy')]
    

    最も簡単なSELECT count(*) FROM tableを実現するために、次のように呼び出すことができます.
    >>> session.query(func.count('*')).select_from(User).scalar()
    SELECT count(?) AS count_1
    FROM users
    ('*',)
    4
    
    Userのプライマリ・キーをカウントする場合、select_fromは省略してもよい.
    >>> session.query(func.count(User.id)).scalar()
    SELECT count(users.id) AS count_1
    FROM users
    ()
    4
    

    次のチュートリアルでは、SQLAlchemyの「関係」の処理方法と、関係に対するより複雑なクエリーについて説明します.
    チュートリアルの第3部転送ゲートSQLAlchemy ORMチュートリアルの3:Relationship