feat: MongoDB class (Mongo kept as alias) + connect()/async with + exists/delete aliases

additive only — every existing name preserved, swallow contract unchanged. brings mongo
in line with the redis/psql/mysql datastore trio's naming/lifecycle. bump v0.1.3 -> v0.1.4

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-06-29 23:11:11 -04:00
parent 1d55efbcdd
commit e20368287d
4 changed files with 87 additions and 17 deletions
+30 -6
View File
@@ -8,31 +8,39 @@ helpers for the common paths, with a raw escape hatch for everything else.
`requirements.txt`:
```
mongo @ git+ssh://git@git.rethinkstudios.io/rethink-public/mongo.git@v0.1.3
mongo @ git+ssh://git@git.rethinkstudios.io/rethink-public/mongo.git@v0.1.4
```
Direct:
```bash
pip install "mongo @ git+ssh://git@git.rethinkstudios.io/rethink-public/mongo.git@v0.1.3"
pip install "mongo @ git+ssh://git@git.rethinkstudios.io/rethink-public/mongo.git@v0.1.4"
```
Requires `motor` and `pymongo` (pulled transitively).
Drop the `@v0.1.3` suffix from the line above to install the latest unpinned.
Drop the `@v0.1.4` suffix from the line above to install the latest unpinned.
## Usage
**Object (preferred)** — one client per process:
```python
from mongo import Mongo
from mongo import MongoDB
db = Mongo(conn_string, database) # attach as bot.db / app.db
db = MongoDB(conn_string, database) # attach as bot.db / app.db
await db.connect() # optional: ping to fail-early on a bad URI
users = await db.get_documents("users", {"active": True})
db.close() # on shutdown (sync)
# or with guaranteed cleanup:
async with MongoDB(conn_string, database) as db:
await db.get_documents("users", {"active": True})
```
The class is `MongoDB`; **`Mongo` remains a back-compat alias** (`Mongo = MongoDB`), so
existing `Mongo(...)` call sites keep working unchanged.
**Module proxy (back-compat)** — arm once, then call bare:
```python
@@ -44,10 +52,26 @@ users = await mongo.get_documents("users", {"active": True})
Both styles share one client. The proxy exists so legacy call sites keep working
after a one-line `init()`; new code should use the object.
## Naming consistency with the datastore trio
mongo predates the `redis`/`psql`/`mysql` trio; this version makes it surface-consistent
**without breaking anything** (all additive, every old name preserved):
- class is **`MongoDB`** (with `Mongo` kept as an alias)
- **`connect()`** + **`async with`** like the trio (motor connects lazily, so `connect()`
just pings to validate early)
- **`exists()`** aliases `check_document_exists()`; **`delete()`** aliases
`delete_document()` — old names still work, the trio-consistent names are now available
The one deliberate difference that remains: **mongo swallows** (see below) where the trio
is **fail-loud**. That's intentional — flipping it would break existing consumers' branch-
on-result control flow.
## Error contract
- **Wrapped methods** log-and-swallow exceptions and return a safe default
(`False` / `[]` / `{}` / `0` / `None`). Branch on the result.
(`False` / `[]` / `{}` / `0` / `None`). Branch on the result. (`connect()` is the
exception — it raises on a bad connection so you can fail-early.)
- **`db.collection(name)`** (or `db[name]`) returns the raw motor collection:
full driver surface, no swallowing, **raises**. Use it for anything not wrapped
(`find_one_and_*` beyond what's exposed, change streams, complex bulk ops).