Add support for MongoDB 3.6 and Python3.7 in travis

This commit is contained in:
Bastien Gérard 2019-05-17 23:07:30 +02:00
parent 58b0b18ddd
commit 2e01eb87db
6 changed files with 38 additions and 24 deletions

View File

@ -25,8 +25,14 @@ elif [ "$MONGODB" = "3.4" ]; then
sudo apt-get update sudo apt-get update
sudo apt-get install mongodb-org-server=3.4.17 sudo apt-get install mongodb-org-server=3.4.17
# service should be started automatically # service should be started automatically
elif [ "$MONGODB" = "3.6" ]; then
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
sudo apt-get update
sudo apt-get install mongodb-org-server=3.6.12
# service should be started automatically
else else
echo "Invalid MongoDB version, expected 2.6, 3.0, 3.2 or 3.4." echo "Invalid MongoDB version, expected 2.6, 3.0, 3.2, 3.4 or 3.6."
exit 1 exit 1
fi; fi;

View File

@ -35,6 +35,8 @@ matrix:
env: MONGODB=3.2 PYMONGO=3.x env: MONGODB=3.2 PYMONGO=3.x
- python: 3.6 - python: 3.6
env: MONGODB=3.4 PYMONGO=3.x env: MONGODB=3.4 PYMONGO=3.x
- python: 3.6
env: MONGODB=3.6 PYMONGO=3.x
before_install: before_install:
- bash .install_mongodb_on_travis.sh - bash .install_mongodb_on_travis.sh

View File

@ -26,10 +26,10 @@ an `API reference <https://mongoengine-odm.readthedocs.io/apireference.html>`_.
Supported MongoDB Versions Supported MongoDB Versions
========================== ==========================
MongoEngine is currently tested against MongoDB v2.6, v3.0, v3.2 and v3.4. Future MongoEngine is currently tested against MongoDB v2.6, v3.0, v3.2, v3.4 and v3.6. Future
versions should be supported as well, but aren't actively tested at the moment. versions should be supported as well, but aren't actively tested at the moment.
Make sure to open an issue or submit a pull request if you experience any Make sure to open an issue or submit a pull request if you experience any
problems with MongoDB v3.4+. problems with MongoDB v3.6+.
Installation Installation
============ ============

View File

@ -4,6 +4,7 @@ Changelog
Development Development
=========== ===========
- Add support for MongoDB 3.6 and Python3.7 in travis
- Fix querying on List(EmbeddedDocument) subclasses fields #1961 #1492 - Fix querying on List(EmbeddedDocument) subclasses fields #1961 #1492
- Fix querying on (Generic)EmbeddedDocument subclasses fields #475 - Fix querying on (Generic)EmbeddedDocument subclasses fields #475
- expose `mongoengine.connection.disconnect` and `mongoengine.connection.disconnect_all` - expose `mongoengine.connection.disconnect` and `mongoengine.connection.disconnect_all`

View File

@ -6,6 +6,7 @@ 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_36 = (3, 6)
MONGODB_34 = (3, 4) MONGODB_34 = (3, 4)
MONGODB_32 = (3, 2) MONGODB_32 = (3, 2)
MONGODB_3 = (3, 0) MONGODB_3 = (3, 0)

View File

@ -6,7 +6,6 @@ import uuid
from decimal import Decimal from decimal import Decimal
from bson import DBRef, ObjectId from bson import DBRef, ObjectId
from nose.plugins.skip import SkipTest
import pymongo import pymongo
from pymongo.errors import ConfigurationError from pymongo.errors import ConfigurationError
from pymongo.read_preferences import ReadPreference from pymongo.read_preferences import ReadPreference
@ -18,7 +17,7 @@ from mongoengine import *
from mongoengine.connection import get_connection, get_db from mongoengine.connection import get_connection, 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 get_mongodb_version, MONGODB_32 from mongoengine.mongodb_support import get_mongodb_version, MONGODB_32, MONGODB_36
from mongoengine.pymongo_support import IS_PYMONGO_3 from mongoengine.pymongo_support import IS_PYMONGO_3
from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned, from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned,
QuerySet, QuerySetManager, queryset_manager) QuerySet, QuerySetManager, queryset_manager)
@ -33,6 +32,12 @@ class db_ops_tracker(query_counter):
return list(self.db.system.profile.find(ignore_query)) return list(self.db.system.profile.find(ignore_query))
def get_key_compat(mongo_ver):
ORDER_BY_KEY = 'sort' if mongo_ver >= MONGODB_32 else '$orderby'
CMD_QUERY_KEY = 'command' if mongo_ver >= MONGODB_36 else 'query'
return ORDER_BY_KEY, CMD_QUERY_KEY
class QuerySetTest(unittest.TestCase): class QuerySetTest(unittest.TestCase):
def setUp(self): def setUp(self):
@ -1323,8 +1328,7 @@ class QuerySetTest(unittest.TestCase):
"""Ensure that the default ordering can be cleared by calling """Ensure that the default ordering can be cleared by calling
order_by() w/o any arguments. order_by() w/o any arguments.
""" """
MONGO_VER = self.mongodb_version ORDER_BY_KEY, CMD_QUERY_KEY = get_key_compat(self.mongodb_version)
ORDER_BY_KEY = 'sort' if MONGO_VER >= MONGODB_32 else '$orderby'
class BlogPost(Document): class BlogPost(Document):
title = StringField() title = StringField()
@ -1341,7 +1345,7 @@ class QuerySetTest(unittest.TestCase):
BlogPost.objects.filter(title='whatever').first() BlogPost.objects.filter(title='whatever').first()
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertEqual( self.assertEqual(
q.get_ops()[0]['query'][ORDER_BY_KEY], q.get_ops()[0][CMD_QUERY_KEY][ORDER_BY_KEY],
{'published_date': -1} {'published_date': -1}
) )
@ -1349,14 +1353,14 @@ class QuerySetTest(unittest.TestCase):
with db_ops_tracker() as q: with db_ops_tracker() as q:
BlogPost.objects.filter(title='whatever').order_by().first() BlogPost.objects.filter(title='whatever').order_by().first()
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0][CMD_QUERY_KEY])
# calling an explicit order_by should use a specified sort # calling an explicit order_by should use a specified sort
with db_ops_tracker() as q: with db_ops_tracker() as q:
BlogPost.objects.filter(title='whatever').order_by('published_date').first() BlogPost.objects.filter(title='whatever').order_by('published_date').first()
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertEqual( self.assertEqual(
q.get_ops()[0]['query'][ORDER_BY_KEY], q.get_ops()[0][CMD_QUERY_KEY][ORDER_BY_KEY],
{'published_date': 1} {'published_date': 1}
) )
@ -1365,13 +1369,12 @@ class QuerySetTest(unittest.TestCase):
qs = BlogPost.objects.filter(title='whatever').order_by('published_date') qs = BlogPost.objects.filter(title='whatever').order_by('published_date')
qs.order_by().first() qs.order_by().first()
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0][CMD_QUERY_KEY])
def test_no_ordering_for_get(self): def test_no_ordering_for_get(self):
""" Ensure that Doc.objects.get doesn't use any ordering. """ Ensure that Doc.objects.get doesn't use any ordering.
""" """
MONGO_VER = self.mongodb_version ORDER_BY_KEY, CMD_QUERY_KEY = get_key_compat(self.mongodb_version)
ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby'
class BlogPost(Document): class BlogPost(Document):
title = StringField() title = StringField()
@ -1387,13 +1390,13 @@ class QuerySetTest(unittest.TestCase):
with db_ops_tracker() as q: with db_ops_tracker() as q:
BlogPost.objects.get(title='whatever') BlogPost.objects.get(title='whatever')
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0][CMD_QUERY_KEY])
# Ordering should be ignored for .get even if we set it explicitly # Ordering should be ignored for .get even if we set it explicitly
with db_ops_tracker() as q: with db_ops_tracker() as q:
BlogPost.objects.order_by('-title').get(title='whatever') BlogPost.objects.order_by('-title').get(title='whatever')
self.assertEqual(len(q.get_ops()), 1) self.assertEqual(len(q.get_ops()), 1)
self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0][CMD_QUERY_KEY])
def test_find_embedded(self): def test_find_embedded(self):
"""Ensure that an embedded document is properly returned from """Ensure that an embedded document is properly returned from
@ -2532,6 +2535,7 @@ class QuerySetTest(unittest.TestCase):
def test_comment(self): def test_comment(self):
"""Make sure adding a comment to the query gets added to the query""" """Make sure adding a comment to the query gets added to the query"""
MONGO_VER = self.mongodb_version MONGO_VER = self.mongodb_version
_, CMD_QUERY_KEY = get_key_compat(MONGO_VER)
QUERY_KEY = 'filter' if MONGO_VER >= MONGODB_32 else '$query' QUERY_KEY = 'filter' if MONGO_VER >= MONGODB_32 else '$query'
COMMENT_KEY = 'comment' if MONGO_VER >= MONGODB_32 else '$comment' COMMENT_KEY = 'comment' if MONGO_VER >= MONGODB_32 else '$comment'
@ -2550,8 +2554,8 @@ class QuerySetTest(unittest.TestCase):
ops = q.get_ops() ops = q.get_ops()
self.assertEqual(len(ops), 2) self.assertEqual(len(ops), 2)
for op in ops: for op in ops:
self.assertEqual(op['query'][QUERY_KEY], {'age': {'$gte': 18}}) self.assertEqual(op[CMD_QUERY_KEY][QUERY_KEY], {'age': {'$gte': 18}})
self.assertEqual(op['query'][COMMENT_KEY], 'looking for an adult') self.assertEqual(op[CMD_QUERY_KEY][COMMENT_KEY], 'looking for an adult')
def test_map_reduce(self): def test_map_reduce(self):
"""Ensure map/reduce is both mapping and reducing. """Ensure map/reduce is both mapping and reducing.
@ -5240,8 +5244,7 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(op['nreturned'], 1) self.assertEqual(op['nreturned'], 1)
def test_bool_with_ordering(self): def test_bool_with_ordering(self):
MONGO_VER = self.mongodb_version ORDER_BY_KEY, CMD_QUERY_KEY = get_key_compat(self.mongodb_version)
ORDER_BY_KEY = 'sort' if MONGO_VER >= MONGODB_32 else '$orderby'
class Person(Document): class Person(Document):
name = StringField() name = StringField()
@ -5260,21 +5263,22 @@ class QuerySetTest(unittest.TestCase):
op = q.db.system.profile.find({"ns": op = q.db.system.profile.find({"ns":
{"$ne": "%s.system.indexes" % q.db.name}})[0] {"$ne": "%s.system.indexes" % q.db.name}})[0]
self.assertNotIn(ORDER_BY_KEY, op['query']) self.assertNotIn(ORDER_BY_KEY, op[CMD_QUERY_KEY])
# Check that normal query uses orderby # Check that normal query uses orderby
qs2 = Person.objects.order_by('name') qs2 = Person.objects.order_by('name')
with query_counter() as p: with query_counter() as q:
for x in qs2: for x in qs2:
pass pass
op = p.db.system.profile.find({"ns": op = q.db.system.profile.find({"ns":
{"$ne": "%s.system.indexes" % q.db.name}})[0] {"$ne": "%s.system.indexes" % q.db.name}})[0]
self.assertIn(ORDER_BY_KEY, op['query']) self.assertIn(ORDER_BY_KEY, op[CMD_QUERY_KEY])
def test_bool_with_ordering_from_meta_dict(self): def test_bool_with_ordering_from_meta_dict(self):
ORDER_BY_KEY, CMD_QUERY_KEY = get_key_compat(self.mongodb_version)
class Person(Document): class Person(Document):
name = StringField() name = StringField()
@ -5296,7 +5300,7 @@ class QuerySetTest(unittest.TestCase):
op = q.db.system.profile.find({"ns": op = q.db.system.profile.find({"ns":
{"$ne": "%s.system.indexes" % q.db.name}})[0] {"$ne": "%s.system.indexes" % q.db.name}})[0]
self.assertNotIn('$orderby', op['query'], self.assertNotIn('$orderby', op[CMD_QUERY_KEY],
'BaseQuerySet must remove orderby from meta in boolen test') 'BaseQuerySet must remove orderby from meta in boolen test')
self.assertEqual(Person.objects.first().name, 'A') self.assertEqual(Person.objects.first().name, 'A')