アナザービーニー1.0 -モンタージュのODMクエリビルダと🚀🎉


警告!
この品は時代遅れだ.
実際の機能とパターンを使用するビーニーの現在のドキュメントに従ってください.
ドキュメントへのリンクhttps://roman-right.github.io/beanie/
ご紹介してうれしいですBeanie 1.0.0 - MongoDB用のPython ODM (オブジェクトドキュメントマッパー)
ヵ月前、私は非常に最初のビーニーリリースを発表しました.あなたはそれについての記事を見つけることができます.私は、それがどのように簡単で、FastAPIとビーニーでCRUDサービスをするためにそこに示されました.
以来、多くの機能が追加されました.今日、私はこの主要なバージョン最新版で来た最も面白いものを示したいです.
このデモでは、Product ドキュメントモデル.
from beanie import Document
from pydantic import BaseModel


class Category(BaseModel):
    name: str
    description: str


class Product(Document):
    name: str
    description: Optional[str] = None
    price: Indexed(float, pymongo.DESCENDING)
    category: Category
    num: int

    class Collection:
        name = "products"
        indexes = [
            [
                ("name", pymongo.TEXT),
                ("description", pymongo.TEXT),
            ],
        ]
ビーニー文書は、Pydantic Basemodelの上の抽象です.これは、ドキュメントを柔軟にし、同時に構築するのに役立ちます.
このデモでは、次の2つの方法でインデックスを設定します.
  • シンプルでIndexed フィールド
  • より複雑なCollection インナークラス
  • ドキュメントの設定に関する詳細はlink

    ドキュメントの作成
    Beanieは単一のドキュメント作成パターンとバッチ挿入を提供します.
    chocolate = Category(name="Chocolate")
    
    # One
    caramel_and_nougat = Product(name="Caramel and Nougat ", 
                                 num=20,
                                 price=3.05,
                                 category=chocolate)
    await caramel_and_nougat.create()
    
    # Many
    peanut_bar = Product(name="Peanut Bar", 
                         num=4, 
                         price=4.44,
                         category=chocolate)
    truffle = Product(name="Chocolate Truffle", 
                      num=40, 
                      price=2.50,
                      category=chocolate)
    await Product.insert_many([peanut_bar, truffle])
    

    クエリを見つける
    これで、Pythonのネイティブ比較演算子をドキュメントクラスフィールドで使用できます.
    Product.find(Product.category.name == "Chocolate")
    
    The find() メソッドはFindMany クエリは、asyncジェネレータを使用して、データを介して利用できるasync for ループ.
    async for item in Product.find(
            Product.category.name == "Chocolate"
    ):
        print(item)
    
    リストを取得するにはto_list() メソッド.
    products = await Product.find(
        Product.category.name == "Chocolate"
    ).to_list()
    
    FindMany クエリはソート、スキップ、制限、およびプロジェクトメソッドも提供します.
    class ProductShortView(BaseModel):
        name: str
        price: float
    
    
    products = await Product.find(
        Product.category.name == "Chocolate",
        Product.price < 3.5
    ).sort(-Product.price).limit(10).project(ProductShortView)
    
    
    Python比較演算子はすべてのケースをカバーしません.Beanieは検索演算子のリストを提供します.
    from beanie.operators import Text
    
    products = await Product.find(Text("Chocolate")).to_list()
    
    find演算子のリスト全体を見つけることができますhere
    ここで微調整するためのネイティブのPyMongo構文を使用できます.
    products = await Product.find({"price": {"gte": 2}}).to_list()
    
    単一のドキュメントを見つける必要がある場合は、find_one 代わりにメソッド.
    product = await Product.find_one(Product.name == "Peanut Bar")
    
    ドキュメントの検索に関する詳細なチュートリアルはlink

    更新update() メソッドは、FindMany and FindOne クエリ.
    アップデート演算子を使用すると、次のようになります.
    from beanie.operators import Inc, Set
    
    # Many
    await Product.find(
        Product.name == "Peanut Bar"
    ).update(Set({Product.price: 5}))
    
    # One
    await Product.find_one(
        Product.name == "Chocolate Truffle"
    ).update(Set({Product.price: 3}))
    
    # or
    
    product = await Product.find_one(Product.name == "Peanut Bar")
    await product.update(Inc({Product.price: -1}))
    
    更新演算子のリストはlink
    ネイティブpymongoの構文もサポートされて
    await Product.find(
        Product.num <= 5
    ).update({"$set": {Product.price: 1}})
    
    
    また、メソッドとして使用できるプリセットの更新操作の一覧があります.インクリメント
    await Product.find(
        Product.category.name == "Chocolate"
    ).inc({Product.price: 2})
    
    検索クエリなしですべてのドキュメントを更新するにはfind ステップ
    await Product.inc({Product.price: 2})
    

    集計
    集計として、更新として使用することができます全体のコレクションまたはFindMany 探索基準
    class TotalCountView(BaseModel):
        category: str = Field(None, alias="_id")
        total: int
    
    
    # Over collection
    
    total_count = await Product.aggregate(
        [{"$group": {"_id": "$category", "total": {"$sum": "$num"}}}],
        projection_model=TotalCountView
    ).to_list()
    
    # Subset
    
    total_count = await Product.find(Product.price < 10).aggregate(
        [{"$group": {"_id": "$category", "total": {"$sum": "$num"}}}],
        projection_model=TotalCountView
    ).to_list()
    
    更新操作については、人気の集約のためのプリセットメソッドの一覧があります.例えば、平均値:
    avg_choco_price = await Product.find(
        Product.category.name == "Chocolate"
    ).avg(Product.price)
    
    Here すべてのプリセットメソッドでDOCを見つけることができます.

    削除
    操作を削除すると、同じパターンがサポートされます.
    # Many
    await Product.find(
        Product.category.name == "Chocolate").delete()
    
    # One
    product = await Product.find_one(Product.name == "Peanut Bar")
    await product.delete()
    
    # Without fetching
    
    await Product.find_one(
        Product.name == "Chocolate Truffle"
    ).delete()
    

    結論
    私の最初の記事では、ビーニーはマイクロオムだと言いました.接頭辞を削除しますmicro さあ.ビーニーは、クエリビルダ、投影、および移動のような機能の多くのMongoDBの豊富なPythonのODMです.それは私が多くのサービスとアプリケーションを構築するのに役立ちます.私は、それはあまりにも多くの他の開発者を助けることを望む.
    そこには私がそこに加える計画がある.開発に参加するのはいつでも歓迎です.

    リンク
  • Beanie Project
  • Documentation
  • Discord Server