SQLAlchemyを使用した組合せページングクエリー

3145 ワード

背景
最近ウェブを书く时よく1つの问题に出会って、データを検索する时条件を组み合わせて検索する必要があって、しかも结果に対してページを分ける必要があって、ネット上で长い间探して、すべて至る所“参考”で、仕方なく自分で研究するしかなくて、ここで研究の结果は记录しておきます
SQLをつづって組み合わせの検索をします
スペルSQLは最も基本的な方法であり、全体的な実行は難しくないが、SQL注入を引き起こしやすい.しかし、スペルの仕方は少し凝っていて、スペルによって後続への影響も違います.
  • Pythonの構文でフォーマット
  • Pythonでは、文字列のフォーマットが最も便利なのは、format()の方法で文字列の置換を行うことです.例えば、SQLをつづる必要がある場合は、以下の方法で行うことができます."select * from photo_info where {0} {1}".format("a=1", " and b=2")
    この方式は最も原始的な方式と言えるべきで、比較的にSQL注入を引き起こしやすい.また、クエリー条件が複雑になると、文全体が少し気分が悪くなります.
    現在、主流の方法でデータベースを操作するのは、ORMのフレームワークを使用して処理されています.例えば、SQLAlchemyのようなものです.
    SQLAlchemyを使用してクエリーを組み合わせる
    まず、SQLAlchemyは組み合わせクエリー時に要素を動的に削除することをサポートしていません.例えば、4つのクエリー条件があり、1つのフィールドの値が空であれば、この空の値はSQLクエリーに従って、このセグメントを削除することなく、残りの3つのフィールドでクエリーします.
    ORM:
    photoinfo.filter(PhotoDB.PhotoInfo.category == category)
    .filter(PhotoDB.PhotoInfo.is_banner == is_banner)
    .filter(PhotoDB.PhotoInfo.photo_desc.like("%{0}%".format(photo_desc))).filter(PhotoDB
    .PhotoInfo.photo_title.like("%{0}%".format(photo_title))).all()
    
    SQL:
    select * from photo_info where category = "category" and is_banner = "is_banner" and photo_desc = "photo_desc" and photo_title = "photo_title"
    

    上記の例では、4つのフィールドに値がある必要があります.そのうちの1つに値がない場合、SQLはこのようになります.select * from photo_info where category = "" and is_banner = "is_banner" and photo_desc = "photo_desc" and photo_title = "photo_title"は私が望んでいる結果とは異なります.私が望んでいるのは、select * from photo_info where is_banner = "is_banner" and photo_desc = "photo_desc" and photo_title = "photo_title"です.SQLAlchemyはやはり優雅な実現方式があり、SQLに似ているが、全体的に論理がはっきりしているように見える.
        if category:
            photoinfo = photoinfo.filter(PhotoDB.PhotoInfo.category == category)
        if is_banner:
            photoinfo = photoinfo.filter(PhotoDB.PhotoInfo.is_banner == is_banner)
        if photo_desc:
            photoinfo = photoinfo.filter(PhotoDB.PhotoInfo.photo_desc.like("%{0}%".format(photo_desc)))
        if photo_title:
            photoinfo = photoinfo.filter(PhotoDB.PhotoInfo.photo_title.like("%{0}%".format(photo_title)))
        photos = photoinfo.all()
    

    これにより、私が望む効果を達成することができ、SQLAlchemySQLに注入して保護措置を行い、安全問題を引き起こすことはありません.
    ページングクエリ
    ページングクエリの論理は簡単で、SQLAlchemyで実現するのも簡単です.
  • pagenate
  • を用いる.pagenateを使用してページングを処理する場合は、クエリーの方法はBaseQueryと継承する必要があります.そうしないと、この方法が見つかりません.使用方法は次のようになります.
    photos = photoinfo.pagination(1, 10)
    

    クエリ結果は、photos変数のitems、すなわちphotos.itemsを反復すれば得られる
  • は、offset()およびlimit()を使用するoffsetがクエリのオフセット量であるのに対し、limitが返す本数を制限している.
    まとめ
    組合せ条件クエリーとページングにはさまざまな実装方法があります.ロジックが明確で安全に見える方法を選択して符号化する必要があります.これにより、今後のメンテナンスに非常に友好的になります.