Merge pull request #1254 from gilbsgilbs/fix_long_fields_python3

Fix long fields python3
This commit is contained in:
Omer Katz 2016-03-23 15:17:06 +02:00
commit af59d4929e
5 changed files with 62 additions and 27 deletions

View File

@ -235,3 +235,4 @@ that much better:
* Steven Rossiter (https://github.com/BeardedSteve) * Steven Rossiter (https://github.com/BeardedSteve)
* Luo Peng (https://github.com/RussellLuo) * Luo Peng (https://github.com/RussellLuo)
* Bryan Bennett (https://github.com/bbenne10) * Bryan Bennett (https://github.com/bbenne10)
* Gilb's Gilb's (https://github.com/gilbsgilbs)

View File

@ -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 - 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. - Raise `OperationError` when trying to do a `drop_collection` on document with no collection set.
- count on ListField of EmbeddedDocumentField fails. #1187 - count on ListField of EmbeddedDocumentField fails. #1187
- Fixed long fields stored as int32 in Python 3. #1253
Changes in 0.10.6 Changes in 0.10.6
================= =================

View File

@ -20,6 +20,10 @@ else:
import pymongo import pymongo
import gridfs import gridfs
from bson import Binary, DBRef, SON, ObjectId from bson import Binary, DBRef, SON, ObjectId
try:
from bson.int64 import Int64
except ImportError:
Int64 = long
from mongoengine.errors import ValidationError from mongoengine.errors import ValidationError
from mongoengine.python_support import (PY3, bin_type, txt_type, from mongoengine.python_support import (PY3, bin_type, txt_type,
@ -227,6 +231,9 @@ class LongField(BaseField):
pass pass
return value return value
def to_mongo(self, value, **kwargs):
return Int64(value)
def validate(self, value): def validate(self, value):
try: try:
value = long(value) value = long(value)

View File

@ -5,6 +5,7 @@ import sys
sys.path[0:0] = [""] sys.path[0:0] = [""]
import pymongo import pymongo
from random import randint
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
from datetime import datetime from datetime import datetime
@ -16,9 +17,11 @@ __all__ = ("IndexesTest", )
class IndexesTest(unittest.TestCase): class IndexesTest(unittest.TestCase):
_MAX_RAND = 10 ** 10
def setUp(self): 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() self.db = get_db()
class Person(Document): class Person(Document):
@ -32,10 +35,7 @@ class IndexesTest(unittest.TestCase):
self.Person = Person self.Person = Person
def tearDown(self): def tearDown(self):
for collection in self.db.collection_names(): self.connection.drop_database(self.db)
if 'system.' in collection:
continue
self.db.drop_collection(collection)
def test_indexes_document(self): def test_indexes_document(self):
"""Ensure that indexes are used when meta[indexes] is specified for """Ensure that indexes are used when meta[indexes] is specified for
@ -822,33 +822,29 @@ class IndexesTest(unittest.TestCase):
name = StringField(required=True) name = StringField(required=True)
term = StringField(required=True) term = StringField(required=True)
class Report(Document): class ReportEmbedded(Document):
key = EmbeddedDocumentField(CompoundKey, primary_key=True) key = EmbeddedDocumentField(CompoundKey, primary_key=True)
text = StringField() text = StringField()
Report.drop_collection()
my_key = CompoundKey(name="n", term="ok") 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'}}, self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}},
report.to_mongo()) 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): def test_compound_key_dictfield(self):
class Report(Document): class ReportDictField(Document):
key = DictField(primary_key=True) key = DictField(primary_key=True)
text = StringField() text = StringField()
Report.drop_collection()
my_key = {"name": "n", "term": "ok"} 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'}}, self.assertEqual({'text': 'OK', '_id': {'term': 'ok', 'name': 'n'}},
report.to_mongo()) 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): def test_string_indexes(self):
@ -909,26 +905,38 @@ class IndexesTest(unittest.TestCase):
Issue #812 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): class BlogPost(Document):
title = StringField() title = StringField()
slug = StringField(unique=True) slug = StringField(unique=True)
BlogPost.drop_collection() meta = {'db_alias': 'test_indexes_after_database_drop'}
# Create Post #1 try:
post1 = BlogPost(title='test1', slug='test') BlogPost.drop_collection()
post1.save()
# Drop the Database # Create Post #1
self.connection.drop_database(BlogPost._get_db().name) post1 = BlogPost(title='test1', slug='test')
post1.save()
# Re-create Post #1 # Drop the Database
post1 = BlogPost(title='test1', slug='test') connection.drop_database('tempdatabase')
post1.save()
# 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): def test_index_dont_send_cls_option(self):
""" """

View File

@ -12,6 +12,7 @@ import uuid
import math import math
import itertools import itertools
import re import re
import six
try: try:
import dateutil import dateutil
@ -21,6 +22,10 @@ except ImportError:
from decimal import Decimal from decimal import Decimal
from bson import Binary, DBRef, ObjectId from bson import Binary, DBRef, ObjectId
try:
from bson.int64 import Int64
except ImportError:
Int64 = long
from mongoengine import * from mongoengine import *
from mongoengine.connection import get_db from mongoengine.connection import get_db
@ -3605,6 +3610,19 @@ class FieldTest(unittest.TestCase):
self.assertRaises(FieldDoesNotExist, test) 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): class EmbeddedDocumentListFieldTestCase(unittest.TestCase):