diff --git a/AUTHORS b/AUTHORS index ad070b30..758c52ea 100644 --- a/AUTHORS +++ b/AUTHORS @@ -235,3 +235,4 @@ that much better: * Steven Rossiter (https://github.com/BeardedSteve) * Luo Peng (https://github.com/RussellLuo) * Bryan Bennett (https://github.com/bbenne10) + * Gilb's Gilb's (https://github.com/gilbsgilbs) diff --git a/docs/changelog.rst b/docs/changelog.rst index 69555b95..c34094a7 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -9,6 +9,7 @@ Changes in 0.10.7 - DEV - Add `signal_kwargs` argument to `Document.save`, `Document.delete` and `BaseQuerySet.insert` to be passed to signals calls #1206 - Raise `OperationError` when trying to do a `drop_collection` on document with no collection set. - count on ListField of EmbeddedDocumentField fails. #1187 +- Fixed long fields stored as int32 in Python 3. #1253 Changes in 0.10.6 ================= diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 6f69465c..c807809a 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -20,6 +20,10 @@ else: import pymongo import gridfs from bson import Binary, DBRef, SON, ObjectId +try: + from bson.int64 import Int64 +except ImportError: + Int64 = long from mongoengine.errors import ValidationError from mongoengine.python_support import (PY3, bin_type, txt_type, @@ -227,6 +231,9 @@ class LongField(BaseField): pass return value + def to_mongo(self, value, **kwargs): + return Int64(value) + def validate(self, value): try: value = long(value) diff --git a/tests/document/indexes.py b/tests/document/indexes.py index 7ee017a6..e13d8b84 100644 --- a/tests/document/indexes.py +++ b/tests/document/indexes.py @@ -5,6 +5,7 @@ import sys sys.path[0:0] = [""] import pymongo +from random import randint from nose.plugins.skip import SkipTest from datetime import datetime @@ -16,9 +17,11 @@ __all__ = ("IndexesTest", ) class IndexesTest(unittest.TestCase): + _MAX_RAND = 10 ** 10 def setUp(self): - self.connection = connect(db='mongoenginetest') + self.db_name = 'mongoenginetest_IndexesTest_' + str(randint(0, self._MAX_RAND)) + self.connection = connect(db=self.db_name) self.db = get_db() class Person(Document): @@ -32,10 +35,7 @@ class IndexesTest(unittest.TestCase): self.Person = Person def tearDown(self): - for collection in self.db.collection_names(): - if 'system.' in collection: - continue - self.db.drop_collection(collection) + self.connection.drop_database(self.db) def test_indexes_document(self): """Ensure that indexes are used when meta[indexes] is specified for @@ -822,33 +822,29 @@ class IndexesTest(unittest.TestCase): name = StringField(required=True) term = StringField(required=True) - class Report(Document): + class ReportEmbedded(Document): key = EmbeddedDocumentField(CompoundKey, primary_key=True) text = StringField() - Report.drop_collection() - my_key = CompoundKey(name="n", term="ok") - report = Report(text="OK", key=my_key).save() + report = ReportEmbedded(text="OK", key=my_key).save() self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}}, report.to_mongo()) - self.assertEqual(report, Report.objects.get(pk=my_key)) + self.assertEqual(report, ReportEmbedded.objects.get(pk=my_key)) def test_compound_key_dictfield(self): - class Report(Document): + class ReportDictField(Document): key = DictField(primary_key=True) text = StringField() - Report.drop_collection() - my_key = {"name": "n", "term": "ok"} - report = Report(text="OK", key=my_key).save() + report = ReportDictField(text="OK", key=my_key).save() self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}}, report.to_mongo()) - self.assertEqual(report, Report.objects.get(pk=my_key)) + self.assertEqual(report, ReportDictField.objects.get(pk=my_key)) def test_string_indexes(self): @@ -909,26 +905,38 @@ class IndexesTest(unittest.TestCase): Issue #812 """ + # Use a new connection and database since dropping the database could + # cause concurrent tests to fail. + connection = connect(db='tempdatabase', + alias='test_indexes_after_database_drop') + class BlogPost(Document): title = StringField() slug = StringField(unique=True) - BlogPost.drop_collection() + meta = {'db_alias': 'test_indexes_after_database_drop'} - # Create Post #1 - post1 = BlogPost(title='test1', slug='test') - post1.save() + try: + BlogPost.drop_collection() - # Drop the Database - self.connection.drop_database(BlogPost._get_db().name) + # Create Post #1 + post1 = BlogPost(title='test1', slug='test') + post1.save() - # Re-create Post #1 - post1 = BlogPost(title='test1', slug='test') - post1.save() + # Drop the Database + connection.drop_database('tempdatabase') + + # Re-create Post #1 + post1 = BlogPost(title='test1', slug='test') + post1.save() + + # Create Post #2 + post2 = BlogPost(title='test2', slug='test') + self.assertRaises(NotUniqueError, post2.save) + finally: + # Drop the temporary database at the end + connection.drop_database('tempdatabase') - # Create Post #2 - post2 = BlogPost(title='test2', slug='test') - self.assertRaises(NotUniqueError, post2.save) def test_index_dont_send_cls_option(self): """ diff --git a/tests/fields/fields.py b/tests/fields/fields.py index 1c1f49ad..9af87f7f 100644 --- a/tests/fields/fields.py +++ b/tests/fields/fields.py @@ -12,6 +12,7 @@ import uuid import math import itertools import re +import six try: import dateutil @@ -21,6 +22,10 @@ except ImportError: from decimal import Decimal from bson import Binary, DBRef, ObjectId +try: + from bson.int64 import Int64 +except ImportError: + Int64 = long from mongoengine import * from mongoengine.connection import get_db @@ -3605,6 +3610,19 @@ class FieldTest(unittest.TestCase): self.assertRaises(FieldDoesNotExist, test) + def test_long_field_is_considered_as_int64(self): + """ + Tests that long fields are stored as long in mongo, even if long value + is small enough to be an int. + """ + class TestLongFieldConsideredAsInt64(Document): + some_long = LongField() + + doc = TestLongFieldConsideredAsInt64(some_long=42).save() + db = get_db() + self.assertTrue(isinstance(db.test_long_field_considered_as_int64.find()[0]['some_long'], Int64)) + self.assertTrue(isinstance(doc.some_long, six.integer_types)) + class EmbeddedDocumentListFieldTestCase(unittest.TestCase):