Skip to main content

MongoDB read-write separation router for mongoengine ODM with transaction-aware and consistent hash routing

Project description

Mongoengine Read-Write Router

A MongoDB read-write separation solution for mongoengine ODM, inspired by the django-rw-router architecture.

This library routes write operations to the primary database and read operations to replica set members, with configurable consistency strategies.

Features

  • Automatic read-write routing - Writes go to primary, reads go to replicas
  • Multiple consistency strategies - random, transaction-aware, consistent hashing
  • Read-after-write consistency - Ensures you see your own writes
  • Request context tracking - Thread-safe context using contextvars
  • Web framework integration - Middleware for FastAPI, Flask, and Django
  • Force primary reads - Explicit control when you need fresh data
  • Write operation tracking - Automatic context updates on writes

Installation

pip install mongoengine-rw-router

Configure 配置方式

支持三种配置方式,按场景选择:

方式 场景 说明
configure() 手动模式 用户自行 connect(),仅配置路由
configure_from_url() 单 URL 副本集 阿里云等,同一 URL + 不同 read_preference
configure_from_hosts() 主从分离 主库与从库使用不同连接串

方式 1:configure_from_url(单 URL,推荐)

适用于副本集单连接串(含 replicaSet、authSource、多节点、用户名密码):

from mongoengine import Document, StringField
from mongoengine_rw_router import RwDocumentMixin, configure_from_url

# 阿里云 / 自建副本集等
host = "mongodb://root:xx@node1:3717,node2:3717/?replicaSet=mgset-xxx&authSource=admin"
configure_from_url(host=host, db="myapp")

class User(RwDocumentMixin, Document):
    name = StringField()
    meta = {"db_alias": "default"}

user = User.objects.first()  # 读从库
user.save()  # 写主库

方式 2:configure_from_hosts(主从分离 URL)

主库与从库使用不同连接串时:

from mongoengine_rw_router import configure_from_hosts

configure_from_hosts(
    primary_host="mongodb://primary:27017",
    replica_hosts=["mongodb://replica1:27017", "mongodb://replica2:27017"],
    db="myapp",
)

方式 3:configure(手动模式)

用户自行调用 mongoengine.connect()

from mongoengine import connect
from pymongo.read_preferences import ReadPreference
from mongoengine_rw_router import configure

connect(db="myapp", alias="default", host="mongodb://primary:27017")
connect(db="myapp", alias="replica1", host="mongodb://replica1:27017",
        read_preference=ReadPreference.SECONDARY_PREFERRED)

configure(primary_alias="default", replica_aliases=["replica1"])

Strategy Options

策略 配置 一致性
random 基础读写分离 最终一致 (Eventual Consistency)
transaction_aware 事务内 + 写后读主库 Read Your Writes
consistent_hash 同一 user_id 固定从库 Monotonic Reads / Consistent Prefix

一致性场景 (DDIA)

django-rw-router 一致,支持 DDIA 第四章复制滞后导致的四种读一致性问题:

场景 含义 推荐配置
Read Your Writes 写入后立即读可见 strategy="transaction_aware" + read_after_write_consistency=True + transaction_read_primary=True
Monotonic Reads 同一用户不出现时光倒流 strategy="consistent_hash" + 中间件注入 user_id
Consistent Prefix 有序读取不出现乱序 strategy="consistent_hash"(同 Monotonic Reads)
Eventual Consistency 接受复制滞后 strategy="random"

配置示例

# Read Your Writes(推荐,默认)
configure(
    primary_alias="default",
    replica_aliases=["replica1", "replica2"],
    strategy="transaction_aware",
    read_after_write_consistency=True,
    transaction_read_primary=True,
)

# Monotonic Reads / Consistent Prefix(需中间件注入 user_id)
configure(
    strategy="consistent_hash",
    hash_virtual_nodes=40,
)
app.add_middleware(MongoRouterMiddleware, user_id_attr="user.id")

# Eventual Consistency
configure(strategy="random")

强制主库读

# 方式 1:primary_queryset
user = User.primary_queryset().first()

# 方式 2:force_primary 链式调用
user = User.objects.force_primary().first()

# 方式 3:force_primary 上下文
from mongoengine_rw_router import force_primary
with force_primary():
    user = User.objects.first()

License

MIT

Credits

Inspired by django-rw-router

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongoengine_rw_router-0.0.3.tar.gz (38.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mongoengine_rw_router-0.0.3-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file mongoengine_rw_router-0.0.3.tar.gz.

File metadata

  • Download URL: mongoengine_rw_router-0.0.3.tar.gz
  • Upload date:
  • Size: 38.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for mongoengine_rw_router-0.0.3.tar.gz
Algorithm Hash digest
SHA256 d81499c15472b24bb9871979d1122cd9e1a700aa53bcf3313797235a05143b94
MD5 33fdea73f3da4abaf586534003322443
BLAKE2b-256 dc31d5bf003afdad3026c7b1686f8a54f7a1b5734ab8b2fd58a9f2ef9067fb88

See more details on using hashes here.

File details

Details for the file mongoengine_rw_router-0.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for mongoengine_rw_router-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 34562a7b413ff853e7b0dac409da63788bf5c2546f549e0f934abf8579e91946
MD5 8445d290023a78399556d52e013003c8
BLAKE2b-256 72edbcb9fc6352c3d397e740a59e9f6cc76f96856f865c95672af29c7597a94a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page