Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
04c26acdd6 | ||
|
d0a15a8924 | ||
|
2215e2746b | ||
|
0e6bcbc030 | ||
|
232071f8f4 | ||
|
fc0fb31d43 | ||
|
1bd8cd803e | ||
|
ef57a58155 | ||
|
9680259904 | ||
|
49a4d23371 | ||
|
b9d370c885 | ||
|
e5a2714baf | ||
|
ff596fcb7e | ||
|
f0fad6df19 | ||
|
da173cf0e2 | ||
|
1669f0c5a4 | ||
|
b045925efe | ||
|
b3ce65453a | ||
|
50d891cb7b | ||
|
e31f9150d2 | ||
|
74ceb9703b | ||
|
58a3c6de03 | ||
|
8fd969aba9 |
2
.github/workflows/github-actions.yml
vendored
2
.github/workflows/github-actions.yml
vendored
@@ -140,4 +140,4 @@ jobs:
|
|||||||
- name: publish pypi
|
- name: publish pypi
|
||||||
uses: pypa/gh-action-pypi-publish@master
|
uses: pypa/gh-action-pypi-publish@master
|
||||||
with:
|
with:
|
||||||
password: ${{ secrets.pypi_token }}
|
password: ${{ secrets.pypi_token }}
|
||||||
|
@@ -1,17 +1,26 @@
|
|||||||
fail_fast: false
|
fail_fast: false
|
||||||
repos:
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v3.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: debug-statements
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
- repo: https://github.com/ambv/black
|
- repo: https://github.com/ambv/black
|
||||||
rev: 20.8b1
|
rev: 21.4b2
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: https://gitlab.com/pycqa/flake8
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
rev: 3.8.4
|
rev: 3.9.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
additional_dependencies:
|
|
||||||
- flake8-import-order
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v2.7.4
|
rev: v2.14.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py36-plus]
|
args: [--py36-plus]
|
||||||
|
- repo: https://github.com/pycqa/isort
|
||||||
|
rev: 5.8.0
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
1
AUTHORS
1
AUTHORS
@@ -259,3 +259,4 @@ that much better:
|
|||||||
* Agustin Barto (https://github.com/abarto)
|
* Agustin Barto (https://github.com/abarto)
|
||||||
* Stankiewicz Mateusz (https://github.com/mas15)
|
* Stankiewicz Mateusz (https://github.com/mas15)
|
||||||
* Felix Schultheiß (https://github.com/felix-smashdocs)
|
* Felix Schultheiß (https://github.com/felix-smashdocs)
|
||||||
|
* Jan Stein (https://github.com/janste63)
|
||||||
|
@@ -35,8 +35,8 @@ Travis runs the tests against the main Python 3.x versions.
|
|||||||
Style Guide
|
Style Guide
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
MongoEngine's codebase is formatted with `black <https://github.com/python/black>`_, other tools like
|
MongoEngine's codebase is auto-formatted with `black <https://github.com/python/black>`_, imports are ordered with `isort <https://pycqa.github.io/isort/>`_
|
||||||
flake8 are also used. Those tools will run as part of the CI and will fail in case the code is not formatted properly.
|
and other tools like flake8 are also used. Those tools will run as part of the CI and will fail in case the code is not formatted properly.
|
||||||
|
|
||||||
To install all development tools, simply run the following commands:
|
To install all development tools, simply run the following commands:
|
||||||
|
|
||||||
@@ -58,6 +58,10 @@ To enable ``pre-commit`` simply run:
|
|||||||
See the ``.pre-commit-config.yaml`` configuration file for more information
|
See the ``.pre-commit-config.yaml`` configuration file for more information
|
||||||
on how it works.
|
on how it works.
|
||||||
|
|
||||||
|
pre-commit will now run upon every commit and will reject anything that doesn't comply.
|
||||||
|
|
||||||
|
You can also run all the checks with ``pre-commit run -a``, this is what is used in the CI.
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ myNoddys = noddy.find()
|
|||||||
print("-" * 100)
|
print("-" * 100)
|
||||||
print("PyMongo: Creating 10000 dictionaries.")
|
print("PyMongo: Creating 10000 dictionaries.")
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
stmt = """
|
stmt = """
|
||||||
from pymongo import MongoClient, WriteConcern
|
from pymongo import MongoClient, WriteConcern
|
||||||
@@ -54,7 +54,7 @@ myNoddys = noddy.find()
|
|||||||
print("-" * 100)
|
print("-" * 100)
|
||||||
print('PyMongo: Creating 10000 dictionaries (write_concern={"w": 0}).')
|
print('PyMongo: Creating 10000 dictionaries (write_concern={"w": 0}).')
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
setup = """
|
setup = """
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
@@ -84,7 +84,7 @@ myNoddys = Noddy.objects()
|
|||||||
print("-" * 100)
|
print("-" * 100)
|
||||||
print("MongoEngine: Creating 10000 dictionaries.")
|
print("MongoEngine: Creating 10000 dictionaries.")
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
stmt = """
|
stmt = """
|
||||||
for i in range(10000):
|
for i in range(10000):
|
||||||
@@ -102,7 +102,7 @@ myNoddys = Noddy.objects()
|
|||||||
print("-" * 100)
|
print("-" * 100)
|
||||||
print("MongoEngine: Creating 10000 dictionaries (using a single field assignment).")
|
print("MongoEngine: Creating 10000 dictionaries (using a single field assignment).")
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
stmt = """
|
stmt = """
|
||||||
for i in range(10000):
|
for i in range(10000):
|
||||||
@@ -118,7 +118,7 @@ myNoddys = Noddy.objects()
|
|||||||
print("-" * 100)
|
print("-" * 100)
|
||||||
print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}).')
|
print('MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}).')
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
stmt = """
|
stmt = """
|
||||||
for i in range(10000):
|
for i in range(10000):
|
||||||
@@ -136,7 +136,7 @@ myNoddys = Noddy.objects()
|
|||||||
'MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}, validate=False).'
|
'MongoEngine: Creating 10000 dictionaries (write_concern={"w": 0}, validate=False).'
|
||||||
)
|
)
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
stmt = """
|
stmt = """
|
||||||
for i in range(10000):
|
for i in range(10000):
|
||||||
@@ -154,7 +154,7 @@ myNoddys = Noddy.objects()
|
|||||||
'MongoEngine: Creating 10000 dictionaries (force_insert=True, write_concern={"w": 0}, validate=False).'
|
'MongoEngine: Creating 10000 dictionaries (force_insert=True, write_concern={"w": 0}, validate=False).'
|
||||||
)
|
)
|
||||||
t = timeit.Timer(stmt=stmt, setup=setup)
|
t = timeit.Timer(stmt=stmt, setup=setup)
|
||||||
print("{}s".format(t.timeit(1)))
|
print(f"{t.timeit(1)}s")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -8,8 +8,13 @@ Development
|
|||||||
===========
|
===========
|
||||||
- (Fill this out as you fix issues and develop your features).
|
- (Fill this out as you fix issues and develop your features).
|
||||||
|
|
||||||
Changes in 0.23.0
|
Changes in 0.23.1
|
||||||
===========
|
===========
|
||||||
|
- Bug fix: ignore LazyReferenceFields when clearing _changed_fields #2484
|
||||||
|
- Improve connection doc #2481
|
||||||
|
|
||||||
|
Changes in 0.23.0
|
||||||
|
=================
|
||||||
- Bugfix: manually setting SequenceField in DynamicDocument doesn't increment the counter #2471
|
- Bugfix: manually setting SequenceField in DynamicDocument doesn't increment the counter #2471
|
||||||
- Add MongoDB 4.2 and 4.4 to CI
|
- Add MongoDB 4.2 and 4.4 to CI
|
||||||
- Add support for allowDiskUse on querysets #2468
|
- Add support for allowDiskUse on querysets #2468
|
||||||
|
@@ -5,7 +5,7 @@ Connecting to MongoDB
|
|||||||
=====================
|
=====================
|
||||||
|
|
||||||
Connections in MongoEngine are registered globally and are identified with aliases.
|
Connections in MongoEngine are registered globally and are identified with aliases.
|
||||||
If no `alias` is provided during the connection, it will use "default" as alias.
|
If no ``alias`` is provided during the connection, it will use "default" as alias.
|
||||||
|
|
||||||
To connect to a running instance of :program:`mongod`, use the :func:`~mongoengine.connect`
|
To connect to a running instance of :program:`mongod`, use the :func:`~mongoengine.connect`
|
||||||
function. The first argument is the name of the database to connect to::
|
function. The first argument is the name of the database to connect to::
|
||||||
@@ -14,27 +14,66 @@ function. The first argument is the name of the database to connect to::
|
|||||||
connect('project1')
|
connect('project1')
|
||||||
|
|
||||||
By default, MongoEngine assumes that the :program:`mongod` instance is running
|
By default, MongoEngine assumes that the :program:`mongod` instance is running
|
||||||
on **localhost** on port **27017**. If MongoDB is running elsewhere, you should
|
on **localhost** on port **27017**.
|
||||||
provide the :attr:`host` and :attr:`port` arguments to
|
|
||||||
:func:`~mongoengine.connect`::
|
|
||||||
|
|
||||||
connect('project1', host='192.168.1.35', port=12345)
|
If MongoDB is running elsewhere, you need to provide details on how to connect. There are two ways of
|
||||||
|
doing this. Using a connection string in URI format (**this is the preferred method**) or individual attributes
|
||||||
|
provided as keyword arguments.
|
||||||
|
|
||||||
|
Connect with URI string
|
||||||
|
=======================
|
||||||
|
|
||||||
|
When using a connection string in URI format you should specify the connection details
|
||||||
|
as the :attr:`host` to :func:`~mongoengine.connect`. In a web application context for instance, the URI
|
||||||
|
is typically read from the config file::
|
||||||
|
|
||||||
|
connect(host="mongodb://127.0.0.1:27017/my_db")
|
||||||
|
|
||||||
|
If the database requires authentication, you can specify it in the
|
||||||
|
URI. As each database can have its own users configured, you need to tell MongoDB
|
||||||
|
where to look for the user you are working with, that's what the ``?authSource=admin`` bit
|
||||||
|
of the MongoDB connection string is for::
|
||||||
|
|
||||||
|
# Connects to 'my_db' database by authenticating
|
||||||
|
# with given credentials against the 'admin' database (by default as authSource isn't provided)
|
||||||
|
connect(host="mongodb://my_user:my_password@127.0.0.1:27017/my_db")
|
||||||
|
|
||||||
|
# Equivalent to previous connection but explicitly states that
|
||||||
|
# it should use admin as the authentication source database
|
||||||
|
connect(host="mongodb://my_user:my_password@hostname:port/my_db?authSource=admin")
|
||||||
|
|
||||||
|
# Connects to 'my_db' database by authenticating
|
||||||
|
# with given credentials against that same database
|
||||||
|
connect(host="mongodb://my_user:my_password@127.0.0.1:27017/my_db?authSource=my_db")
|
||||||
|
|
||||||
|
The URI string can also be used to configure advanced parameters like ssl, replicaSet, etc. For more
|
||||||
|
information or example about URI string, you can refer to the `official doc <https://docs.mongodb.com/manual/reference/connection-string/>`_::
|
||||||
|
|
||||||
|
connect(host="mongodb://my_user:my_password@127.0.0.1:27017/my_db?authSource=admin&ssl=true&replicaSet=globaldb")
|
||||||
|
|
||||||
|
.. note:: URI containing SRV records (e.g "mongodb+srv://server.example.com/") can be used as well
|
||||||
|
|
||||||
|
Connect with keyword attributes
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The second option for specifying the connection details is to provide the information as keyword
|
||||||
|
attributes to :func:`~mongoengine.connect`::
|
||||||
|
|
||||||
|
connect('my_db', host='127.0.0.1', port=27017)
|
||||||
|
|
||||||
If the database requires authentication, :attr:`username`, :attr:`password`
|
If the database requires authentication, :attr:`username`, :attr:`password`
|
||||||
and :attr:`authentication_source` arguments should be provided::
|
and :attr:`authentication_source` arguments should be provided::
|
||||||
|
|
||||||
connect('project1', username='webapp', password='pwd123', authentication_source='admin')
|
connect('my_db', username='my_user', password='my_password', authentication_source='admin')
|
||||||
|
|
||||||
URI style connections are also supported -- just supply the URI as
|
The set of attributes that :func:`~mongoengine.connect` recognizes includes but is not limited to:
|
||||||
the :attr:`host` to
|
:attr:`host`, :attr:`port`, :attr:`read_preference`, :attr:`username`, :attr:`password`, :attr:`authentication_source`, :attr:`authentication_mechanism`,
|
||||||
:func:`~mongoengine.connect`::
|
:attr:`replicaset`, :attr:`tls`, etc. Most of the parameters accepted by `pymongo.MongoClient <https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient>`_
|
||||||
|
can be used with :func:`~mongoengine.connect` and will simply be forwarded when instantiating the `pymongo.MongoClient`.
|
||||||
connect('project1', host='mongodb://localhost/database_name')
|
|
||||||
|
|
||||||
.. note:: URI containing SRV records (e.g mongodb+srv://server.example.com/) can be used as well as the :attr:`host`
|
|
||||||
|
|
||||||
.. note:: Database, username and password from URI string overrides
|
.. note:: Database, username and password from URI string overrides
|
||||||
corresponding parameters in :func:`~mongoengine.connect`: ::
|
corresponding parameters in :func:`~mongoengine.connect`, this should
|
||||||
|
obviously be avoided: ::
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
db='test',
|
db='test',
|
||||||
@@ -43,28 +82,19 @@ the :attr:`host` to
|
|||||||
host='mongodb://admin:qwerty@localhost/production'
|
host='mongodb://admin:qwerty@localhost/production'
|
||||||
)
|
)
|
||||||
|
|
||||||
will establish connection to ``production`` database using
|
will establish connection to ``production`` database using ``admin`` username and ``qwerty`` password.
|
||||||
``admin`` username and ``12345`` password.
|
|
||||||
|
|
||||||
.. note:: Calling :func:`~mongoengine.connect` without argument will establish
|
.. note:: Calling :func:`~mongoengine.connect` without argument will establish
|
||||||
a connection to the "test" database by default
|
a connection to the "test" database by default
|
||||||
|
|
||||||
Replica Sets
|
Read Preferences
|
||||||
============
|
================
|
||||||
|
|
||||||
MongoEngine supports connecting to replica sets::
|
As stated above, Read preferences are supported through the connection but also via individual
|
||||||
|
|
||||||
from mongoengine import connect
|
|
||||||
|
|
||||||
# Regular connect
|
|
||||||
connect('dbname', replicaset='rs-name')
|
|
||||||
|
|
||||||
# MongoDB URI-style connect
|
|
||||||
connect(host='mongodb://localhost/dbname?replicaSet=rs-name')
|
|
||||||
|
|
||||||
Read preferences are supported through the connection or via individual
|
|
||||||
queries by passing the read_preference ::
|
queries by passing the read_preference ::
|
||||||
|
|
||||||
|
from pymongo import ReadPreference
|
||||||
|
|
||||||
Bar.objects().read_preference(ReadPreference.PRIMARY)
|
Bar.objects().read_preference(ReadPreference.PRIMARY)
|
||||||
Bar.objects(read_preference=ReadPreference.PRIMARY)
|
Bar.objects(read_preference=ReadPreference.PRIMARY)
|
||||||
|
|
||||||
|
@@ -290,12 +290,12 @@ as the constructor's argument::
|
|||||||
content = StringField()
|
content = StringField()
|
||||||
|
|
||||||
|
|
||||||
.. _one-to-many-with-listfields:
|
.. _many-to-many-with-listfields:
|
||||||
|
|
||||||
One to Many with ListFields
|
Many to Many with ListFields
|
||||||
'''''''''''''''''''''''''''
|
'''''''''''''''''''''''''''
|
||||||
|
|
||||||
If you are implementing a one to many relationship via a list of references,
|
If you are implementing a many to many relationship via a list of references,
|
||||||
then the references are stored as DBRefs and to query you need to pass an
|
then the references are stored as DBRefs and to query you need to pass an
|
||||||
instance of the object to the query::
|
instance of the object to the query::
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ existing ``User`` model with a `default=True`. Thus you simply update the ``User
|
|||||||
|
|
||||||
class User(Document):
|
class User(Document):
|
||||||
name = StringField(required=True)
|
name = StringField(required=True)
|
||||||
enabled = BooleaField(default=True)
|
enabled = BooleanField(default=True)
|
||||||
|
|
||||||
Without applying any migration, we now reload an object from the database into the ``User`` class
|
Without applying any migration, we now reload an object from the database into the ``User`` class
|
||||||
and checks its `enabled` attribute:
|
and checks its `enabled` attribute:
|
||||||
|
@@ -120,4 +120,3 @@ the validation and cleaning of a document when you call :meth:`~mongoengine.docu
|
|||||||
Person(age=1000).save(validate=False)
|
Person(age=1000).save(validate=False)
|
||||||
person = Person.objects.first()
|
person = Person.objects.first()
|
||||||
assert person.age == 1000
|
assert person.age == 1000
|
||||||
|
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
# Import submodules so that we can expose their __all__
|
# Import submodules so that we can expose their __all__
|
||||||
from mongoengine import connection
|
from mongoengine import (
|
||||||
from mongoengine import document
|
connection,
|
||||||
from mongoengine import errors
|
document,
|
||||||
from mongoengine import fields
|
errors,
|
||||||
from mongoengine import queryset
|
fields,
|
||||||
from mongoengine import signals
|
queryset,
|
||||||
|
signals,
|
||||||
|
)
|
||||||
|
|
||||||
# Import everything from each submodule so that it can be accessed via
|
# Import everything from each submodule so that it can be accessed via
|
||||||
# mongoengine, e.g. instead of `from mongoengine.connection import connect`,
|
# mongoengine, e.g. instead of `from mongoengine.connection import connect`,
|
||||||
@@ -17,7 +19,6 @@ from mongoengine.fields import * # noqa: F401
|
|||||||
from mongoengine.queryset import * # noqa: F401
|
from mongoengine.queryset import * # noqa: F401
|
||||||
from mongoengine.signals import * # noqa: F401
|
from mongoengine.signals import * # noqa: F401
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
list(document.__all__)
|
list(document.__all__)
|
||||||
+ list(fields.__all__)
|
+ list(fields.__all__)
|
||||||
@@ -28,7 +29,7 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
VERSION = (0, 23, 0)
|
VERSION = (0, 23, 1)
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
import numbers
|
import numbers
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from bson import DBRef, ObjectId, SON, json_util
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from bson import SON, DBRef, ObjectId, json_util
|
||||||
|
|
||||||
from mongoengine import signals
|
from mongoengine import signals
|
||||||
from mongoengine.base.common import get_document
|
from mongoengine.base.common import get_document
|
||||||
@@ -615,7 +614,9 @@ class BaseDocument:
|
|||||||
def _get_changed_fields(self):
|
def _get_changed_fields(self):
|
||||||
"""Return a list of all fields that have explicitly been changed."""
|
"""Return a list of all fields that have explicitly been changed."""
|
||||||
EmbeddedDocument = _import_class("EmbeddedDocument")
|
EmbeddedDocument = _import_class("EmbeddedDocument")
|
||||||
|
LazyReferenceField = _import_class("LazyReferenceField")
|
||||||
ReferenceField = _import_class("ReferenceField")
|
ReferenceField = _import_class("ReferenceField")
|
||||||
|
GenericLazyReferenceField = _import_class("GenericLazyReferenceField")
|
||||||
GenericReferenceField = _import_class("GenericReferenceField")
|
GenericReferenceField = _import_class("GenericReferenceField")
|
||||||
SortedListField = _import_class("SortedListField")
|
SortedListField = _import_class("SortedListField")
|
||||||
|
|
||||||
@@ -641,7 +642,13 @@ class BaseDocument:
|
|||||||
changed_fields += [f"{key}{k}" for k in changed if k]
|
changed_fields += [f"{key}{k}" for k in changed if k]
|
||||||
elif isinstance(data, (list, tuple, dict)):
|
elif isinstance(data, (list, tuple, dict)):
|
||||||
if hasattr(field, "field") and isinstance(
|
if hasattr(field, "field") and isinstance(
|
||||||
field.field, (ReferenceField, GenericReferenceField)
|
field.field,
|
||||||
|
(
|
||||||
|
LazyReferenceField,
|
||||||
|
ReferenceField,
|
||||||
|
GenericLazyReferenceField,
|
||||||
|
GenericReferenceField,
|
||||||
|
),
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
elif isinstance(field, SortedListField) and field._ordering:
|
elif isinstance(field, SortedListField) and field._ordering:
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
import operator
|
import operator
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from bson import DBRef, ObjectId, SON
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from bson import SON, DBRef, ObjectId
|
||||||
|
|
||||||
from mongoengine.base.common import UPDATE_OPERATORS
|
from mongoengine.base.common import UPDATE_OPERATORS
|
||||||
from mongoengine.base.datastructures import BaseDict, BaseList, EmbeddedDocumentList
|
from mongoengine.base.datastructures import (
|
||||||
|
BaseDict,
|
||||||
|
BaseList,
|
||||||
|
EmbeddedDocumentList,
|
||||||
|
)
|
||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
from mongoengine.errors import DeprecatedError, ValidationError
|
from mongoengine.errors import DeprecatedError, ValidationError
|
||||||
|
|
||||||
@@ -267,6 +271,17 @@ class ComplexBaseField(BaseField):
|
|||||||
self.field = field
|
self.field = field
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _lazy_load_refs(instance, name, ref_values, *, max_depth):
|
||||||
|
_dereference = _import_class("DeReference")()
|
||||||
|
documents = _dereference(
|
||||||
|
ref_values,
|
||||||
|
max_depth=max_depth,
|
||||||
|
instance=instance,
|
||||||
|
name=name,
|
||||||
|
)
|
||||||
|
return documents
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
"""Descriptor to automatically dereference references."""
|
"""Descriptor to automatically dereference references."""
|
||||||
if instance is None:
|
if instance is None:
|
||||||
@@ -284,19 +299,15 @@ class ComplexBaseField(BaseField):
|
|||||||
or isinstance(self.field, (GenericReferenceField, ReferenceField))
|
or isinstance(self.field, (GenericReferenceField, ReferenceField))
|
||||||
)
|
)
|
||||||
|
|
||||||
_dereference = _import_class("DeReference")()
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
instance._initialised
|
instance._initialised
|
||||||
and dereference
|
and dereference
|
||||||
and instance._data.get(self.name)
|
and instance._data.get(self.name)
|
||||||
and not getattr(instance._data[self.name], "_dereferenced", False)
|
and not getattr(instance._data[self.name], "_dereferenced", False)
|
||||||
):
|
):
|
||||||
instance._data[self.name] = _dereference(
|
ref_values = instance._data.get(self.name)
|
||||||
instance._data.get(self.name),
|
instance._data[self.name] = self._lazy_load_refs(
|
||||||
max_depth=1,
|
ref_values=ref_values, instance=instance, name=self.name, max_depth=1
|
||||||
instance=instance,
|
|
||||||
name=self.name,
|
|
||||||
)
|
)
|
||||||
if hasattr(instance._data[self.name], "_dereferenced"):
|
if hasattr(instance._data[self.name], "_dereferenced"):
|
||||||
instance._data[self.name]._dereferenced = True
|
instance._data[self.name]._dereferenced = True
|
||||||
@@ -322,7 +333,9 @@ class ComplexBaseField(BaseField):
|
|||||||
and isinstance(value, (BaseList, BaseDict))
|
and isinstance(value, (BaseList, BaseDict))
|
||||||
and not value._dereferenced
|
and not value._dereferenced
|
||||||
):
|
):
|
||||||
value = _dereference(value, max_depth=1, instance=instance, name=self.name)
|
value = self._lazy_load_refs(
|
||||||
|
ref_values=value, instance=instance, name=self.name, max_depth=1
|
||||||
|
)
|
||||||
value._dereferenced = True
|
value._dereferenced = True
|
||||||
instance._data[self.name] = value
|
instance._data[self.name] = value
|
||||||
|
|
||||||
|
@@ -2,7 +2,11 @@ import itertools
|
|||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from mongoengine.base.common import _document_registry
|
from mongoengine.base.common import _document_registry
|
||||||
from mongoengine.base.fields import BaseField, ComplexBaseField, ObjectIdField
|
from mongoengine.base.fields import (
|
||||||
|
BaseField,
|
||||||
|
ComplexBaseField,
|
||||||
|
ObjectIdField,
|
||||||
|
)
|
||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
from mongoengine.errors import InvalidDocumentError
|
from mongoengine.errors import InvalidDocumentError
|
||||||
from mongoengine.queryset import (
|
from mongoengine.queryset import (
|
||||||
@@ -12,7 +16,6 @@ from mongoengine.queryset import (
|
|||||||
QuerySetManager,
|
QuerySetManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("DocumentMetaclass", "TopLevelDocumentMetaclass")
|
__all__ = ("DocumentMetaclass", "TopLevelDocumentMetaclass")
|
||||||
|
|
||||||
|
|
||||||
|
@@ -217,8 +217,8 @@ def register_connection(
|
|||||||
|
|
||||||
def disconnect(alias=DEFAULT_CONNECTION_NAME):
|
def disconnect(alias=DEFAULT_CONNECTION_NAME):
|
||||||
"""Close the connection with a given alias."""
|
"""Close the connection with a given alias."""
|
||||||
from mongoengine.base.common import _get_documents_by_db
|
|
||||||
from mongoengine import Document
|
from mongoengine import Document
|
||||||
|
from mongoengine.base.common import _get_documents_by_db
|
||||||
|
|
||||||
if alias in _connections:
|
if alias in _connections:
|
||||||
get_connection(alias=alias).close()
|
get_connection(alias=alias).close()
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from bson import DBRef, SON
|
from bson import SON, DBRef
|
||||||
|
|
||||||
from mongoengine.base import (
|
from mongoengine.base import (
|
||||||
BaseDict,
|
BaseDict,
|
||||||
@@ -10,7 +10,12 @@ from mongoengine.base import (
|
|||||||
from mongoengine.base.datastructures import LazyReference
|
from mongoengine.base.datastructures import LazyReference
|
||||||
from mongoengine.connection import get_db
|
from mongoengine.connection import get_db
|
||||||
from mongoengine.document import Document, EmbeddedDocument
|
from mongoengine.document import Document, EmbeddedDocument
|
||||||
from mongoengine.fields import DictField, ListField, MapField, ReferenceField
|
from mongoengine.fields import (
|
||||||
|
DictField,
|
||||||
|
ListField,
|
||||||
|
MapField,
|
||||||
|
ReferenceField,
|
||||||
|
)
|
||||||
from mongoengine.queryset import QuerySet
|
from mongoengine.queryset import QuerySet
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from bson.dbref import DBRef
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from bson.dbref import DBRef
|
||||||
from pymongo.read_preferences import ReadPreference
|
from pymongo.read_preferences import ReadPreference
|
||||||
|
|
||||||
from mongoengine import signals
|
from mongoengine import signals
|
||||||
@@ -16,14 +16,23 @@ from mongoengine.base import (
|
|||||||
)
|
)
|
||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
||||||
from mongoengine.context_managers import set_write_concern, switch_collection, switch_db
|
from mongoengine.context_managers import (
|
||||||
|
set_write_concern,
|
||||||
|
switch_collection,
|
||||||
|
switch_db,
|
||||||
|
)
|
||||||
from mongoengine.errors import (
|
from mongoengine.errors import (
|
||||||
InvalidDocumentError,
|
InvalidDocumentError,
|
||||||
InvalidQueryError,
|
InvalidQueryError,
|
||||||
SaveConditionError,
|
SaveConditionError,
|
||||||
)
|
)
|
||||||
from mongoengine.pymongo_support import list_collection_names
|
from mongoengine.pymongo_support import list_collection_names
|
||||||
from mongoengine.queryset import NotUniqueError, OperationError, QuerySet, transform
|
from mongoengine.queryset import (
|
||||||
|
NotUniqueError,
|
||||||
|
OperationError,
|
||||||
|
QuerySet,
|
||||||
|
transform,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Document",
|
"Document",
|
||||||
@@ -323,7 +332,7 @@ class Document(BaseDocument, metaclass=TopLevelDocumentMetaclass):
|
|||||||
_refs=None,
|
_refs=None,
|
||||||
save_condition=None,
|
save_condition=None,
|
||||||
signal_kwargs=None,
|
signal_kwargs=None,
|
||||||
**kwargs
|
**kwargs,
|
||||||
):
|
):
|
||||||
"""Save the :class:`~mongoengine.Document` to the database. If the
|
"""Save the :class:`~mongoengine.Document` to the database. If the
|
||||||
document already exists, it will be updated, otherwise it will be
|
document already exists, it will be updated, otherwise it will be
|
||||||
@@ -554,7 +563,7 @@ class Document(BaseDocument, metaclass=TopLevelDocumentMetaclass):
|
|||||||
if not getattr(ref, "_changed_fields", True):
|
if not getattr(ref, "_changed_fields", True):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ref_id = "{},{}".format(ref.__class__.__name__, str(ref._data))
|
ref_id = f"{ref.__class__.__name__},{str(ref._data)}"
|
||||||
if ref and ref_id not in _refs:
|
if ref and ref_id not in _refs:
|
||||||
_refs.append(ref_id)
|
_refs.append(ref_id)
|
||||||
kwargs["_refs"] = _refs
|
kwargs["_refs"] = _refs
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"NotRegistered",
|
"NotRegistered",
|
||||||
"InvalidDocumentError",
|
"InvalidDocumentError",
|
||||||
|
@@ -9,10 +9,10 @@ import uuid
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from bson import Binary, DBRef, ObjectId, SON
|
|
||||||
from bson.int64 import Int64
|
|
||||||
import gridfs
|
import gridfs
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from bson import SON, Binary, DBRef, ObjectId
|
||||||
|
from bson.int64 import Int64
|
||||||
from pymongo import ReturnDocument
|
from pymongo import ReturnDocument
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -22,7 +22,6 @@ except ImportError:
|
|||||||
else:
|
else:
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
|
|
||||||
from mongoengine.base import (
|
from mongoengine.base import (
|
||||||
BaseDocument,
|
BaseDocument,
|
||||||
BaseField,
|
BaseField,
|
||||||
@@ -36,7 +35,11 @@ from mongoengine.base.utils import LazyRegexCompiler
|
|||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
||||||
from mongoengine.document import Document, EmbeddedDocument
|
from mongoengine.document import Document, EmbeddedDocument
|
||||||
from mongoengine.errors import DoesNotExist, InvalidQueryError, ValidationError
|
from mongoengine.errors import (
|
||||||
|
DoesNotExist,
|
||||||
|
InvalidQueryError,
|
||||||
|
ValidationError,
|
||||||
|
)
|
||||||
from mongoengine.queryset import DO_NOTHING
|
from mongoengine.queryset import DO_NOTHING
|
||||||
from mongoengine.queryset.base import BaseQuerySet
|
from mongoengine.queryset.base import BaseQuerySet
|
||||||
from mongoengine.queryset.transform import STRING_OPERATORS
|
from mongoengine.queryset.transform import STRING_OPERATORS
|
||||||
@@ -915,7 +918,7 @@ class ListField(ComplexBaseField):
|
|||||||
"""A list field that wraps a standard field, allowing multiple instances
|
"""A list field that wraps a standard field, allowing multiple instances
|
||||||
of the field to be used as a list in the database.
|
of the field to be used as a list in the database.
|
||||||
|
|
||||||
If using with ReferenceFields see: :ref:`one-to-many-with-listfields`
|
If using with ReferenceFields see: :ref:`many-to-many-with-listfields`
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Required means it cannot be empty - as the default for ListFields is []
|
Required means it cannot be empty - as the default for ListFields is []
|
||||||
@@ -1194,6 +1197,14 @@ class ReferenceField(BaseField):
|
|||||||
self.document_type_obj = get_document(self.document_type_obj)
|
self.document_type_obj = get_document(self.document_type_obj)
|
||||||
return self.document_type_obj
|
return self.document_type_obj
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _lazy_load_ref(ref_cls, dbref):
|
||||||
|
dereferenced_son = ref_cls._get_db().dereference(dbref)
|
||||||
|
if dereferenced_son is None:
|
||||||
|
raise DoesNotExist(f"Trying to dereference unknown document {dbref}")
|
||||||
|
|
||||||
|
return ref_cls._from_son(dereferenced_son)
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
"""Descriptor to allow lazy dereferencing."""
|
"""Descriptor to allow lazy dereferencing."""
|
||||||
if instance is None:
|
if instance is None:
|
||||||
@@ -1201,20 +1212,17 @@ class ReferenceField(BaseField):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
# Get value from document instance if available
|
# Get value from document instance if available
|
||||||
value = instance._data.get(self.name)
|
ref_value = instance._data.get(self.name)
|
||||||
auto_dereference = instance._fields[self.name]._auto_dereference
|
auto_dereference = instance._fields[self.name]._auto_dereference
|
||||||
# Dereference DBRefs
|
# Dereference DBRefs
|
||||||
if auto_dereference and isinstance(value, DBRef):
|
if auto_dereference and isinstance(ref_value, DBRef):
|
||||||
if hasattr(value, "cls"):
|
if hasattr(ref_value, "cls"):
|
||||||
# Dereference using the class type specified in the reference
|
# Dereference using the class type specified in the reference
|
||||||
cls = get_document(value.cls)
|
cls = get_document(ref_value.cls)
|
||||||
else:
|
else:
|
||||||
cls = self.document_type
|
cls = self.document_type
|
||||||
dereferenced = cls._get_db().dereference(value)
|
|
||||||
if dereferenced is None:
|
instance._data[self.name] = self._lazy_load_ref(cls, ref_value)
|
||||||
raise DoesNotExist("Trying to dereference unknown document %s" % value)
|
|
||||||
else:
|
|
||||||
instance._data[self.name] = cls._from_son(dereferenced)
|
|
||||||
|
|
||||||
return super().__get__(instance, owner)
|
return super().__get__(instance, owner)
|
||||||
|
|
||||||
@@ -1353,6 +1361,14 @@ class CachedReferenceField(BaseField):
|
|||||||
self.document_type_obj = get_document(self.document_type_obj)
|
self.document_type_obj = get_document(self.document_type_obj)
|
||||||
return self.document_type_obj
|
return self.document_type_obj
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _lazy_load_ref(ref_cls, dbref):
|
||||||
|
dereferenced_son = ref_cls._get_db().dereference(dbref)
|
||||||
|
if dereferenced_son is None:
|
||||||
|
raise DoesNotExist(f"Trying to dereference unknown document {dbref}")
|
||||||
|
|
||||||
|
return ref_cls._from_son(dereferenced_son)
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
if instance is None:
|
if instance is None:
|
||||||
# Document class being used rather than a document object
|
# Document class being used rather than a document object
|
||||||
@@ -1364,11 +1380,7 @@ class CachedReferenceField(BaseField):
|
|||||||
|
|
||||||
# Dereference DBRefs
|
# Dereference DBRefs
|
||||||
if auto_dereference and isinstance(value, DBRef):
|
if auto_dereference and isinstance(value, DBRef):
|
||||||
dereferenced = self.document_type._get_db().dereference(value)
|
instance._data[self.name] = self._lazy_load_ref(self.document_type, value)
|
||||||
if dereferenced is None:
|
|
||||||
raise DoesNotExist("Trying to dereference unknown document %s" % value)
|
|
||||||
else:
|
|
||||||
instance._data[self.name] = self.document_type._from_son(dereferenced)
|
|
||||||
|
|
||||||
return super().__get__(instance, owner)
|
return super().__get__(instance, owner)
|
||||||
|
|
||||||
@@ -1493,6 +1505,14 @@ class GenericReferenceField(BaseField):
|
|||||||
value = value._class_name
|
value = value._class_name
|
||||||
super()._validate_choices(value)
|
super()._validate_choices(value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _lazy_load_ref(ref_cls, dbref):
|
||||||
|
dereferenced_son = ref_cls._get_db().dereference(dbref)
|
||||||
|
if dereferenced_son is None:
|
||||||
|
raise DoesNotExist(f"Trying to dereference unknown document {dbref}")
|
||||||
|
|
||||||
|
return ref_cls._from_son(dereferenced_son)
|
||||||
|
|
||||||
def __get__(self, instance, owner):
|
def __get__(self, instance, owner):
|
||||||
if instance is None:
|
if instance is None:
|
||||||
return self
|
return self
|
||||||
@@ -1500,12 +1520,9 @@ class GenericReferenceField(BaseField):
|
|||||||
value = instance._data.get(self.name)
|
value = instance._data.get(self.name)
|
||||||
|
|
||||||
auto_dereference = instance._fields[self.name]._auto_dereference
|
auto_dereference = instance._fields[self.name]._auto_dereference
|
||||||
if auto_dereference and isinstance(value, (dict, SON)):
|
if auto_dereference and isinstance(value, dict):
|
||||||
dereferenced = self.dereference(value)
|
doc_cls = get_document(value["_cls"])
|
||||||
if dereferenced is None:
|
instance._data[self.name] = self._lazy_load_ref(doc_cls, value["_ref"])
|
||||||
raise DoesNotExist("Trying to dereference unknown document %s" % value)
|
|
||||||
else:
|
|
||||||
instance._data[self.name] = dereferenced
|
|
||||||
|
|
||||||
return super().__get__(instance, owner)
|
return super().__get__(instance, owner)
|
||||||
|
|
||||||
@@ -1524,14 +1541,6 @@ class GenericReferenceField(BaseField):
|
|||||||
" saved to the database"
|
" saved to the database"
|
||||||
)
|
)
|
||||||
|
|
||||||
def dereference(self, value):
|
|
||||||
doc_cls = get_document(value["_cls"])
|
|
||||||
reference = value["_ref"]
|
|
||||||
doc = doc_cls._get_db().dereference(reference)
|
|
||||||
if doc is not None:
|
|
||||||
doc = doc_cls._from_son(doc)
|
|
||||||
return doc
|
|
||||||
|
|
||||||
def to_mongo(self, document):
|
def to_mongo(self, document):
|
||||||
if document is None:
|
if document is None:
|
||||||
return None
|
return None
|
||||||
|
@@ -3,7 +3,6 @@ Helper functions, constants, and types to aid with MongoDB version support
|
|||||||
"""
|
"""
|
||||||
from mongoengine.connection import get_connection
|
from mongoengine.connection import get_connection
|
||||||
|
|
||||||
|
|
||||||
# Constant that can be used to compare the version retrieved with
|
# Constant that can be used to compare the version retrieved with
|
||||||
# get_mongodb_version()
|
# get_mongodb_version()
|
||||||
MONGODB_34 = (3, 4)
|
MONGODB_34 = (3, 4)
|
||||||
|
@@ -2,13 +2,12 @@ import copy
|
|||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from bson import SON, json_util
|
|
||||||
from bson.code import Code
|
|
||||||
import pymongo
|
import pymongo
|
||||||
import pymongo.errors
|
import pymongo.errors
|
||||||
|
from bson import SON, json_util
|
||||||
|
from bson.code import Code
|
||||||
from pymongo.collection import ReturnDocument
|
from pymongo.collection import ReturnDocument
|
||||||
from pymongo.common import validate_read_preference
|
from pymongo.common import validate_read_preference
|
||||||
from pymongo.read_concern import ReadConcern
|
from pymongo.read_concern import ReadConcern
|
||||||
@@ -34,7 +33,6 @@ from mongoengine.queryset import transform
|
|||||||
from mongoengine.queryset.field_list import QueryFieldList
|
from mongoengine.queryset.field_list import QueryFieldList
|
||||||
from mongoengine.queryset.visitor import Q, QNode
|
from mongoengine.queryset.visitor import Q, QNode
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("BaseQuerySet", "DO_NOTHING", "NULLIFY", "CASCADE", "DENY", "PULL")
|
__all__ = ("BaseQuerySet", "DO_NOTHING", "NULLIFY", "CASCADE", "DENY", "PULL")
|
||||||
|
|
||||||
# Delete rules
|
# Delete rules
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from mongoengine.queryset.queryset import QuerySet
|
from mongoengine.queryset.queryset import QuerySet
|
||||||
|
|
||||||
__all__ = ("queryset_manager", "QuerySetManager")
|
__all__ = ("queryset_manager", "QuerySetManager")
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
from mongoengine.errors import OperationError
|
from mongoengine.errors import OperationError
|
||||||
from mongoengine.queryset.base import (
|
from mongoengine.queryset.base import (
|
||||||
BaseQuerySet,
|
|
||||||
CASCADE,
|
CASCADE,
|
||||||
DENY,
|
DENY,
|
||||||
DO_NOTHING,
|
DO_NOTHING,
|
||||||
NULLIFY,
|
NULLIFY,
|
||||||
PULL,
|
PULL,
|
||||||
|
BaseQuerySet,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from bson import ObjectId, SON
|
|
||||||
from bson.dbref import DBRef
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
from bson import SON, ObjectId
|
||||||
|
from bson.dbref import DBRef
|
||||||
|
|
||||||
from mongoengine.base import UPDATE_OPERATORS
|
from mongoengine.base import UPDATE_OPERATORS
|
||||||
from mongoengine.common import _import_class
|
from mongoengine.common import _import_class
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
black
|
black
|
||||||
flake8
|
flake8
|
||||||
flake8-import-order
|
|
||||||
pre-commit
|
pre-commit
|
||||||
pytest
|
pytest
|
||||||
ipdb
|
ipdb
|
||||||
|
10
setup.cfg
10
setup.cfg
@@ -2,9 +2,17 @@
|
|||||||
ignore=E501,F403,F405,I201,I202,W504,W605,W503,B007
|
ignore=E501,F403,F405,I201,I202,W504,W605,W503,B007
|
||||||
exclude=build,dist,docs,venv,venv3,.tox,.eggs,tests
|
exclude=build,dist,docs,venv,venv3,.tox,.eggs,tests
|
||||||
max-complexity=47
|
max-complexity=47
|
||||||
application-import-names=mongoengine,tests
|
|
||||||
|
|
||||||
[tool:pytest]
|
[tool:pytest]
|
||||||
# Limits the discovery to tests directory
|
# Limits the discovery to tests directory
|
||||||
# avoids that it runs for instance the benchmark
|
# avoids that it runs for instance the benchmark
|
||||||
testpaths = tests
|
testpaths = tests
|
||||||
|
|
||||||
|
[isort]
|
||||||
|
known_first_party = mongoengine,tests
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma = True
|
||||||
|
combine_as_imports = True
|
||||||
|
line_length = 70
|
||||||
|
ensure_newline_before_comments = 1
|
||||||
|
2
setup.py
2
setup.py
@@ -53,8 +53,8 @@ class PyTest(TestCommand):
|
|||||||
|
|
||||||
def run_tests(self):
|
def run_tests(self):
|
||||||
# import here, cause outside the eggs aren't loaded
|
# import here, cause outside the eggs aren't loaded
|
||||||
from pkg_resources import _namespace_packages
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from pkg_resources import _namespace_packages
|
||||||
|
|
||||||
# Purge modules under test from sys.modules. The test loader will
|
# Purge modules under test from sys.modules. The test loader will
|
||||||
# re-import them from the build location. Required when 2to3 is used
|
# re-import them from the build location. Required when 2to3 is used
|
||||||
|
@@ -177,7 +177,7 @@ class TestClassMethods(unittest.TestCase):
|
|||||||
assert BlogPostWithCustomField.compare_indexes() == {"missing": [], "extra": []}
|
assert BlogPostWithCustomField.compare_indexes() == {"missing": [], "extra": []}
|
||||||
|
|
||||||
def test_compare_indexes_for_text_indexes(self):
|
def test_compare_indexes_for_text_indexes(self):
|
||||||
""" Ensure that compare_indexes behaves correctly for text indexes """
|
"""Ensure that compare_indexes behaves correctly for text indexes"""
|
||||||
|
|
||||||
class Doc(Document):
|
class Doc(Document):
|
||||||
a = StringField()
|
a = StringField()
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bson import SON
|
from bson import SON
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.pymongo_support import list_collection_names
|
from mongoengine.pymongo_support import list_collection_names
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
@@ -1,13 +1,16 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
import pytest
|
||||||
from pymongo.collation import Collation
|
from pymongo.collation import Collation
|
||||||
from pymongo.errors import OperationFailure
|
from pymongo.errors import OperationFailure
|
||||||
import pytest
|
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.connection import get_db
|
from mongoengine.connection import get_db
|
||||||
from mongoengine.mongodb_support import MONGODB_42, get_mongodb_version
|
from mongoengine.mongodb_support import (
|
||||||
|
MONGODB_42,
|
||||||
|
get_mongodb_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestIndexes(unittest.TestCase):
|
class TestIndexes(unittest.TestCase):
|
||||||
|
@@ -6,9 +6,9 @@ import weakref
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import bson
|
import bson
|
||||||
|
import pytest
|
||||||
from bson import DBRef, ObjectId
|
from bson import DBRef, ObjectId
|
||||||
from pymongo.errors import DuplicateKeyError
|
from pymongo.errors import DuplicateKeyError
|
||||||
import pytest
|
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine import signals
|
from mongoengine import signals
|
||||||
@@ -23,7 +23,11 @@ from mongoengine.errors import (
|
|||||||
NotUniqueError,
|
NotUniqueError,
|
||||||
SaveConditionError,
|
SaveConditionError,
|
||||||
)
|
)
|
||||||
from mongoengine.mongodb_support import MONGODB_34, MONGODB_36, get_mongodb_version
|
from mongoengine.mongodb_support import (
|
||||||
|
MONGODB_34,
|
||||||
|
MONGODB_36,
|
||||||
|
get_mongodb_version,
|
||||||
|
)
|
||||||
from mongoengine.pymongo_support import list_collection_names
|
from mongoengine.pymongo_support import list_collection_names
|
||||||
from mongoengine.queryset import NULLIFY, Q
|
from mongoengine.queryset import NULLIFY, Q
|
||||||
from tests import fixtures
|
from tests import fixtures
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from bson import Binary
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import Binary
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
@@ -6,7 +6,6 @@ import re
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,7 +9,6 @@ except ImportError:
|
|||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine import connection
|
from mongoengine import connection
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
from bson import InvalidDocument
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import InvalidDocument
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.base import BaseDict
|
from mongoengine.base import BaseDict
|
||||||
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
from mongoengine.mongodb_support import (
|
||||||
|
MONGODB_36,
|
||||||
|
get_mongodb_version,
|
||||||
|
)
|
||||||
from tests.utils import MongoDBTestCase, get_as_pymongo
|
from tests.utils import MongoDBTestCase, get_as_pymongo
|
||||||
|
|
||||||
|
|
||||||
|
@@ -12,7 +12,6 @@ from mongoengine import (
|
|||||||
StringField,
|
StringField,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from bson import InvalidDocument
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import InvalidDocument
|
||||||
|
|
||||||
from mongoengine import Document, EnumField, ValidationError
|
from mongoengine import Document, EnumField, ValidationError
|
||||||
from tests.utils import MongoDBTestCase, get_as_pymongo
|
from tests.utils import MongoDBTestCase, get_as_pymongo
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bson import DBRef, ObjectId, SON
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import SON, DBRef, ObjectId
|
||||||
|
|
||||||
from mongoengine import (
|
from mongoengine import (
|
||||||
BooleanField,
|
BooleanField,
|
||||||
@@ -34,9 +34,12 @@ from mongoengine import (
|
|||||||
StringField,
|
StringField,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
from mongoengine.base import BaseField, EmbeddedDocumentList, _document_registry
|
from mongoengine.base import (
|
||||||
|
BaseField,
|
||||||
|
EmbeddedDocumentList,
|
||||||
|
_document_registry,
|
||||||
|
)
|
||||||
from mongoengine.errors import DeprecatedError
|
from mongoengine.errors import DeprecatedError
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -308,7 +308,7 @@ class TestFileField(MongoDBTestCase):
|
|||||||
assert test_file.the_file not in [{"test": 1}]
|
assert test_file.the_file not in [{"test": 1}]
|
||||||
|
|
||||||
def test_file_disk_space(self):
|
def test_file_disk_space(self):
|
||||||
""" Test disk space usage when we delete/replace a file """
|
"""Test disk space usage when we delete/replace a file"""
|
||||||
|
|
||||||
class TestFile(Document):
|
class TestFile(Document):
|
||||||
the_file = FileField()
|
the_file = FileField()
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
from bson import DBRef, ObjectId
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import DBRef, ObjectId
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.base import LazyReference
|
from mongoengine.base import LazyReference
|
||||||
from mongoengine.context_managers import query_counter
|
from mongoengine.context_managers import query_counter
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
@@ -375,6 +374,26 @@ class TestLazyReferenceField(MongoDBTestCase):
|
|||||||
assert isinstance(ref.author, LazyReference)
|
assert isinstance(ref.author, LazyReference)
|
||||||
assert isinstance(ref.author.id, ObjectId)
|
assert isinstance(ref.author.id, ObjectId)
|
||||||
|
|
||||||
|
def test_lazy_reference_in_list_with_changed_element(self):
|
||||||
|
class Animal(Document):
|
||||||
|
name = StringField()
|
||||||
|
tag = StringField()
|
||||||
|
|
||||||
|
class Ocurrence(Document):
|
||||||
|
in_list = ListField(LazyReferenceField(Animal))
|
||||||
|
|
||||||
|
Animal.drop_collection()
|
||||||
|
Ocurrence.drop_collection()
|
||||||
|
|
||||||
|
animal1 = Animal(name="doggo").save()
|
||||||
|
|
||||||
|
animal1.tag = "blue"
|
||||||
|
|
||||||
|
occ = Ocurrence(in_list=[animal1]).save()
|
||||||
|
animal1.save()
|
||||||
|
assert isinstance(occ.in_list[0], LazyReference)
|
||||||
|
assert occ.in_list[0].pk == animal1.pk
|
||||||
|
|
||||||
|
|
||||||
class TestGenericLazyReferenceField(MongoDBTestCase):
|
class TestGenericLazyReferenceField(MongoDBTestCase):
|
||||||
def test_generic_lazy_reference_simple(self):
|
def test_generic_lazy_reference_simple(self):
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
from bson.int64 import Int64
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson.int64 import Int64
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.connection import get_db
|
from mongoengine.connection import get_db
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase, get_as_pymongo
|
from tests.utils import MongoDBTestCase, get_as_pymongo
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
from bson import DBRef, SON
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import SON, DBRef
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,7 +2,6 @@ import datetime
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase
|
from tests.utils import MongoDBTestCase
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,12 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from mongoengine import Document, IntField, ListField, StringField, connect
|
from mongoengine import (
|
||||||
|
Document,
|
||||||
|
IntField,
|
||||||
|
ListField,
|
||||||
|
StringField,
|
||||||
|
connect,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Doc(Document):
|
class Doc(Document):
|
||||||
|
@@ -3,17 +3,20 @@ import unittest
|
|||||||
import uuid
|
import uuid
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from bson import DBRef, ObjectId
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
import pytest
|
||||||
|
from bson import DBRef, ObjectId
|
||||||
from pymongo.read_preferences import ReadPreference
|
from pymongo.read_preferences import ReadPreference
|
||||||
from pymongo.results import UpdateResult
|
from pymongo.results import UpdateResult
|
||||||
import pytest
|
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.connection import get_db
|
from mongoengine.connection import get_db
|
||||||
from mongoengine.context_managers import query_counter, switch_db
|
from mongoengine.context_managers import query_counter, switch_db
|
||||||
from mongoengine.errors import InvalidQueryError
|
from mongoengine.errors import InvalidQueryError
|
||||||
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
from mongoengine.mongodb_support import (
|
||||||
|
MONGODB_36,
|
||||||
|
get_mongodb_version,
|
||||||
|
)
|
||||||
from mongoengine.queryset import (
|
from mongoengine.queryset import (
|
||||||
DoesNotExist,
|
DoesNotExist,
|
||||||
MultipleObjectsReturned,
|
MultipleObjectsReturned,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bson.son import SON
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson.son import SON
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.queryset import Q, transform
|
from mongoengine.queryset import Q, transform
|
||||||
|
@@ -2,8 +2,8 @@ import datetime
|
|||||||
import re
|
import re
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bson import ObjectId
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from bson import ObjectId
|
||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.errors import InvalidQueryError
|
from mongoengine.errors import InvalidQueryError
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from bson.tz_util import utc
|
|
||||||
import pymongo
|
import pymongo
|
||||||
|
import pytest
|
||||||
|
from bson.tz_util import utc
|
||||||
from pymongo import MongoClient, ReadPreference
|
from pymongo import MongoClient, ReadPreference
|
||||||
from pymongo.errors import InvalidName, OperationFailure
|
from pymongo.errors import InvalidName, OperationFailure
|
||||||
import pytest
|
|
||||||
|
|
||||||
import mongoengine.connection
|
import mongoengine.connection
|
||||||
from mongoengine import (
|
from mongoengine import (
|
||||||
@@ -17,8 +17,8 @@ from mongoengine import (
|
|||||||
register_connection,
|
register_connection,
|
||||||
)
|
)
|
||||||
from mongoengine.connection import (
|
from mongoengine.connection import (
|
||||||
ConnectionFailure,
|
|
||||||
DEFAULT_DATABASE_NAME,
|
DEFAULT_DATABASE_NAME,
|
||||||
|
ConnectionFailure,
|
||||||
disconnect,
|
disconnect,
|
||||||
get_connection,
|
get_connection,
|
||||||
get_db,
|
get_db,
|
||||||
|
@@ -3,15 +3,9 @@ import unittest
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import mongoengine.connection
|
import mongoengine.connection
|
||||||
from mongoengine import (
|
from mongoengine import Document, StringField, connect, disconnect_all
|
||||||
Document,
|
|
||||||
StringField,
|
|
||||||
connect,
|
|
||||||
disconnect_all,
|
|
||||||
)
|
|
||||||
from mongoengine.connection import get_connection
|
from mongoengine.connection import get_connection
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import mongomock
|
import mongomock
|
||||||
|
|
||||||
|
@@ -3,7 +3,11 @@ import unittest
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from mongoengine import Document
|
from mongoengine import Document
|
||||||
from mongoengine.base.datastructures import BaseDict, BaseList, StrictDict
|
from mongoengine.base.datastructures import (
|
||||||
|
BaseDict,
|
||||||
|
BaseList,
|
||||||
|
StrictDict,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentStub:
|
class DocumentStub:
|
||||||
|
@@ -5,7 +5,6 @@ from pymongo import MongoClient, ReadPreference
|
|||||||
import mongoengine
|
import mongoengine
|
||||||
from mongoengine.connection import ConnectionFailure
|
from mongoengine.connection import ConnectionFailure
|
||||||
|
|
||||||
|
|
||||||
CONN_CLASS = MongoClient
|
CONN_CLASS = MongoClient
|
||||||
READ_PREF = ReadPreference.SECONDARY
|
READ_PREF = ReadPreference.SECONDARY
|
||||||
|
|
||||||
|
@@ -249,7 +249,7 @@ class TestSignal(unittest.TestCase):
|
|||||||
assert self.pre_signals == post_signals
|
assert self.pre_signals == post_signals
|
||||||
|
|
||||||
def test_model_signals(self):
|
def test_model_signals(self):
|
||||||
""" Model saves should throw some signals. """
|
"""Model saves should throw some signals."""
|
||||||
|
|
||||||
def create_author():
|
def create_author():
|
||||||
self.Author(name="Bill Shakespeare")
|
self.Author(name="Bill Shakespeare")
|
||||||
@@ -340,7 +340,7 @@ class TestSignal(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def test_signal_kwargs(self):
|
def test_signal_kwargs(self):
|
||||||
""" Make sure signal_kwargs is passed to signals calls. """
|
"""Make sure signal_kwargs is passed to signals calls."""
|
||||||
|
|
||||||
def live_and_let_die():
|
def live_and_let_die():
|
||||||
a = self.Author(name="Bill Shakespeare")
|
a = self.Author(name="Bill Shakespeare")
|
||||||
@@ -385,7 +385,7 @@ class TestSignal(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def test_queryset_delete_signals(self):
|
def test_queryset_delete_signals(self):
|
||||||
""" Queryset delete should throw some signals. """
|
"""Queryset delete should throw some signals."""
|
||||||
|
|
||||||
self.Another(name="Bill Shakespeare").save()
|
self.Another(name="Bill Shakespeare").save()
|
||||||
assert self.get_signal_output(self.Another.objects.delete) == [
|
assert self.get_signal_output(self.Another.objects.delete) == [
|
||||||
@@ -396,7 +396,7 @@ class TestSignal(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def test_signals_with_explicit_doc_ids(self):
|
def test_signals_with_explicit_doc_ids(self):
|
||||||
""" Model saves must have a created flag the first time."""
|
"""Model saves must have a created flag the first time."""
|
||||||
ei = self.ExplicitId(id=123)
|
ei = self.ExplicitId(id=123)
|
||||||
# post save must received the created flag, even if there's already
|
# post save must received the created flag, even if there's already
|
||||||
# an object id present
|
# an object id present
|
||||||
|
@@ -7,7 +7,6 @@ from mongoengine import connect
|
|||||||
from mongoengine.connection import disconnect_all, get_db
|
from mongoengine.connection import disconnect_all, get_db
|
||||||
from mongoengine.mongodb_support import get_mongodb_version
|
from mongoengine.mongodb_support import get_mongodb_version
|
||||||
|
|
||||||
|
|
||||||
MONGO_TEST_DB = "mongoenginetest" # standard name for the test database
|
MONGO_TEST_DB = "mongoenginetest" # standard name for the test database
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user