Skip to main content

Mongo-Thingy

PyPI Supported Python Versions License Code style
Tests Tests Docs

Mongo-Thingy is the most idiomatic and friendly-yet-powerful way to use MongoDB with Python.

It is an "Object-Document Mapper" that gives you full advantage of MongoDB schema-less design by not asking you to define schemas in your code.

What you'll get:

  • a simple and robust pure-Python code base, with 100% coverage and few dependencies;
  • PyMongo query language - no need to learn yet another one;
  • both sync and async support! choose what suits you best;
  • Thingy views - control what to show, and create fields based on other fields;
  • swappable backend - wanna use SQLite behind the scenes? well, you can;
  • versioning (optional) - rollback to any point in any thingy history;
  • and more!

Compatibility

We support all Python and MongoDB versions supported by PyMongo, namely:

  • CPython 3.7+ and PyPy3.7+
  • MongoDB 3.6, 4.0, 4.2, 4.4, and 5.0.

As a backend, Mongo-Thingy supports the following libraries:

Install

pip install mongo-thingy

Examples

First steps

Connect, insert and find thingies

>>> from mongo_thingy import connect, Thingy
>>> connect("mongodb://localhost/test")

>>> class User(Thingy):
...     pass

>>> user = User({"name": "Mr. Foo", "age": 42}).save()
>>> User.count_documents()
1
>>> User.find_one({"age": 42})
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 42})

In an AsyncIO (or Tornado) environment, use the asynchronous class instead:

>>> from mongo_thingy import connect, AsyncThingy
>>> connect("mongodb://localhost/test")

>>> class User(AsyncThingy):
...     pass

>>> user = await User({"name": "Mr. Foo", "age": 42}).save()
>>> await User.count_documents()
1
>>> await User.find_one({"age": 42})
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 42})

To use another backend than the default ones, just pass its client class with client_cls:

>>> import mongomock
>>> connect(client_cls=mongomock.MongoClient)

Update a thingy

>>> user.age
42
>>> user.age = 1337
>>> user.save()
User({'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337})

Thingy views power

Complete information with properties

>>> class User(Thingy):
...     @property
...     def username(self):
...         return "".join(char for char in self.name if char.isalpha())

>>> User.add_view(name="everything", defaults=True, include="username")
>>> user = User.find_one()
>>> user.view("everything")
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337, 'username': 'MrFoo'}

Hide sensitive stuff

>>> User.add_view(name="public", defaults=True, exclude="password")
>>> user.password = "t0ps3cr3t"
>>> user.view()
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337, 'password': 't0ps3cr3t'}
>>> user.view("public")
{'_id': ObjectId(...), 'name': 'Mr. Foo', 'age': 1337}

Only use certain fields/properties

>>> User.add_view(name="credentials", include=["username", "password"])
>>> user.view("credentials")
{'username': 'MrFoo', 'password': 't0ps3cr3t'}

Apply views on cursors

>>> cursor = User.find()
>>> for credentials in cursor.view("credentials"):
...     print(credentials)
{'username': 'MrFoo', 'password': 't0ps3cr3t'}
{'username': 'MrsBar', 'password': '123456789'}
...

And if your cursor is already exhausted, you can still apply a view!

>>> users = User.find().to_list(None)
>>> for credentials in users.view("credentials"):
...     print(credentials)
{'username': 'MrFoo', 'password': 't0ps3cr3t'}
{'username': 'MrsBar', 'password': '123456789'}
...

Versioning

>>> from mongo_thingy.versioned import Versioned

>>> class Article(Versioned, Thingy):
...     pass

>>> article = Article(content="Cogito ergo sum")
>>> article.version
0

>>> article.save()
Article({'_id': ObjectId('...'), 'content': 'Cogito ergo sum'})
>>> article.version
1

>>> article.content = "Sum ergo cogito"
>>> article.save()
Article({'_id': ObjectId('...'), 'content': 'Sum ergo cogito'})
>>> article.version
2

>>> article.revert()
Article({'_id': ObjectId('...'), 'content': 'Cogito ergo sum'})
>>> article.version
3

Database/collection "discovery"

Default behaviour

>>> class AuthenticationGroup(Thingy):
...     pass

>>> connect("mongodb://localhost/")
>>> AuthenticationGroup.collection
Collection(Database(MongoClient(host=['localhost:27017'], ...), 'authentication'), 'group')

Use mismatching names for Thingy class and database collection

You can either specify the collection name:

>>> class Foo(Thingy):
...   collection_name = "bar"

or the collection directly:

>>> class Foo(Thingy):
...   collection = db.bar

You can then check what collection is being used with:

>>> Foo.collection
Collection(Database(MongoClient('localhost', 27017), 'database'), 'bar')

Indexes

Create an index

>>> User.create_index("email", sparse=True, unique=True)

Add one or more indexes, create later

>>> User.add_index("email", sparse=True, unique=True)
>>> User.add_index("username")

>>> User.create_indexes()

Create all indexes of all thingies at once

>>> from mongo_thingy import create_indexes
>>> create_indexes()

Dealing with camelCase data

>>> from mongo_thingy.camelcase import CamelCase

>>> class SystemUser(CamelCase, Thingy):
...     collection_name = "systemUsers"

>>> user = SystemUser.find_one()
>>> user.view()
{'_id': ObjectId(...), 'firstName': 'John', 'lastName': 'Doe'}

>>> user.first_name
'John'
>>> user.first_name = "Jonny"
>>> user.save()
SystemUser({'_id': ObjectId(...), firstName: 'Jonny', lastName: 'Doe'})

Tests

To run the tests suite:

  • make sure you have a MongoDB database running on localhost:27017 (you can spawn one with docker-compose up -d);
  • install developers requirements with pip install -r requirements.txt;
  • run pytest.

Sponsors

    Numberly         Refty    

Metadata

Release files for Mongo-Thingy 0.17.2

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

Source distribution (sdist)

Source distribution for Mongo-Thingy 0.17.2
File Size Uploaded
Mongo-Thingy-0.17.2.tar.gz 9.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for Mongo-Thingy 0.17.2
File Interpreter ABI Platform
Mongo_Thingy-0.17.2-py3-none-any.whl Python 3 none any Details

Total release size: 19.1 kB

Release files / Mongo-Thingy-0.17.2.tar.gz

Download URL Mongo-Thingy-0.17.2.tar.gz
Size 9.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f83cae3364b688da8985c1d178fb22a2bd930863b9163d08f9778e5ecf87335f
BLAKE2b-256 checksum
How to use checksums
48654794eb1f8045c6d446d7ad3c1e4d2d56ba433cd560cf1f75697ff022e4ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.13

Release files / Mongo_Thingy-0.17.2-py3-none-any.whl

Download URL Mongo_Thingy-0.17.2-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bf9546821125665bab2b3e14b79b3af9b5a4ed2cbdc34e1c2c6592d3a2c11d8f
BLAKE2b-256 checksum
How to use checksums
1ee5f7aa6e34468b9b9c15ca48d4f70e960837a1c378a779f02fc1ac617238d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.13

Release history Release notifications | RSS feed

This release

0.17.2 This release

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.4

1 release file

0.10.3

2 release files

0.10.2

1 release file

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.0

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

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