Skip to main content

Beanie

Getting Started with Beanie

Beanie - is an Asynchronous Python object-document mapper (ODM) for MongoDB, based on Motor and Pydantic.

When using Beanie each database collection has a corresponding Document that is used to interact with that collection. In addition to retrieving data, Beanie allows you to add, update, or delete documents from the collection as well.

Beanie saves you time by removing boiler-plate code and it helps you focus on the parts of your app that actually matter.

Data and schema migrations are supported by Beanie out of the box.

Installation

PIP

pip install beanie

Poetry

poetry add beanie

Basic Example

Document models

from typing import Optional
from pydantic import BaseModel
from beanie import Document, Indexed


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


class Product(Document):  # This is the model
    name: str
    description: Optional[str] = None
    price: Indexed(float)
    category: Category

    class Collection:
        name = "products"

Each document by default has id ObjectId field, which reflects _id MongoDB document field. It can be used later as an argument for the get() method.

More details about Documents, collections, and indexes configuration could be found in the tutorial.

Initialization

import motor
from beanie import init_beanie


async def init():
    # Crete Motor client
    client = motor.motor_asyncio.AsyncIOMotorClient(
        "mongodb://user:pass@host:27017"
    )

    # Init beanie with the Note document class
    await init_beanie(database=client.db_name, document_models=[Product])

Create

chocolate = Category(name="Chocolate")

# Single:

bar = Product(name="Tony's", price=5.95, category=chocolate)
await bar.insert()

# Many

milka = Product(name="Milka", price=3.05, category=chocolate)
peanut_bar = Product(name="Peanut Bar", price=4.44, category=chocolate)
await Product.insert_many([milka, peanut_bar])

Other details and examples could be found in the tutorial

Find

# Single

# By id
bar = await Product.get("608da169eb9e17281f0ab2ff")

# By name
bar = await Product.find_one(Product.name == "Peanut Bar")

# Many

# By category

chocolates = await Product.find(
    Product.category.name == "Chocolate"
).to_list()

# And by price

chocolates = await Product.find(
    Product.category.name == "Chocolate",
    Product.price < 5
).to_list()

# OR

chocolates = await Product.find(
    Product.category.name == "Chocolate").find(
    Product.price < 5).to_list()

# Complex example:

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)

# All

all_products = await Product.all().to_list()

Information about sorting, skips, limits, and projections could be found in the tutorial

Update

# Single 
await Product.find_one(Product.name == "Milka").set({Product.price: 3.33})

# Or
bar = await Product.find_one(Product.name == "Milka")
await bar.update(Set({Product.price: 3.33}))

# Or
bar.price = 3.33
await bar.replace()

# Many
await Product.find(
    Product.category.name == "Chocolate"
).inc({Product.price: 1})

More details and examples about update queries could be found in the tutorial

Delete

# Single 
await Product.find_one(Product.name == "Milka").delete()

# Or
bar = await Product.find_one(Product.name == "Milka")
await bar.delete()

# Many
await Product.find(
    Product.category.name == "Chocolate"
).delete()

More information could be found in the tutorial

Aggregate

# With preset methods

avg_price = await Product.find(
    Product.category.name == "Chocolate"
).avg(Product.price)

# Or without find query

avg_price = await Product.avg(Product.price)

# Native syntax 

class OutputItem(BaseModel):
    id: str = Field(None, alias="_id")
    total: int
    
result = await Product.find(
    Product.category.name == "Chocolate").aggregate(
    [{"$group": {"_id": "$category.name", "total": {"$avg": "$price"}}}],
    projection_model=OutputItem
).to_list()

Information about aggregation preset aggregation methods and native syntax aggregations could be found in the tutorial

Documentation

  • Tutorial - Usage examples with descriptions
  • API - Full list of the classes and methods

Example Projects

  • FastAPI Demo - Beanie and FastAPI collaboration demonstration. CRUD and Aggregation.
  • Indexes Demo - Regular and Geo Indexes usage example wrapped to a microservice.

Articles

Resources

  • GitHub - GitHub page of the project
  • Changelog - list of all the valuable changes
  • Discord - ask your questions, share ideas or just say Hello!!

Supported by JetBrains

JetBrains

Metadata

Release files for beanie 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for beanie 1.0.1
File Size Uploaded Provenance Actions
beanie-1.0.1.tar.gz 29.2 kB Without provenance Details for beanie-1.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for beanie 1.0.1
File Interpreter ABI Platform Actions
beanie-1.0.1-py3-none-any.whl Python 3 none any Details for beanie-1.0.1-py3-none-any.whl

Total release size: 73.9 kB

Release files / beanie-1.0.1.tar.gz

Download URL beanie-1.0.1.tar.gz
Size 29.2 kB
Tags Source
SHA-256 checksum
How to use checksums
a0ba449e5713bc356c0f3d20459a0620de2a7edede211ad8fe2469f7a74a01ab
BLAKE2b-256 checksum
How to use checksums
ab06722e420c6971e4e9341b0dfa5efa52bd0c4495e3b8eb9127417d889b47ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.4 CPython/3.8.5 Linux/5.8.0-48-generic

Release files / beanie-1.0.1-py3-none-any.whl

Download URL beanie-1.0.1-py3-none-any.whl
Size 44.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4b300d85c76fee73eddafd902fa01863b850fb398dc4c262892b7bbfe57e7d75
BLAKE2b-256 checksum
How to use checksums
1d66e1a19ef2a4df950eb3101207668698f72cd4c2bc76f9b109bf800da4e8c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.4 CPython/3.8.5 Linux/5.8.0-48-generic

Security for beanie 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page