django tests, mongoengine, and unique_with constraint

81 views
Skip to first unread message

Loutre

unread,
Feb 25, 2014, 8:21:42 AM2/25/14
to django...@googlegroups.com
Hi everybody,

I'm facing the following problem with Mongodb.

I've got the following model : 


from mongoengine import Document, StringField, DateTimeField


class Author(Document):
    name = StringField(max_length=50, required=True)
    first_name = StringField(max_length=50, required=True, unique_with='name')
    birthday = DateTimeField(default=None)
    death_day = DateTimeField(default=None)

    meta = {
        'indexes': [('name', '+first_name')]
    }

Nothing special there, except that 'firstname' should be unique with 'name'.

I wrote the following test suite :

from django.test import TestCase
from les_classiques.models import Author
import mongoengine


class DatabaseTest(TestCase):
    def setUp(self):
        db = mongoengine.connection.get_db()
        for collection in db.collection_names(include_system_collections=False):
            db.drop_collection(collection)

    def test_insert_new_author(self):
        author = Author(name='Hugo', first_name='Victor')
        author.save()
        db_author = Author.objects(name='Hugo', first_name='Victor')[0]
        self.assertEqual(db_author.name, 'Hugo')

    def test_insert_duplicate_author_failure(self):
        author = Author(name='Peguy', first_name='Charles')
        author2 = Author(name='Peguy', first_name='Charles')
        author.save()
        self.assertRaises(mongoengine.NotUniqueError, author2.save)

The second test fails with the following error : "AssertionError: NotUniqueError not raised by save"


It's very strange. After some tests, I realized that the objects of the second function, are created with a duplicate key :
> db.author.find()
{ "_id" : ObjectId("530c96b7893e2808f8435e49"), "name" : "Peguy", "first_name" : "Charles" }
{ "_id" : ObjectId("530c96b7893e2808f8435e4a"), "name" : "Peguy", "first_name" : "Charles" }

I read the docs, this should work. StringField inherits from BaseField and should accept unique_with parameter.

Any idea ?


Loutre

unread,
Feb 25, 2014, 9:14:24 AM2/25/14
to django...@googlegroups.com
NB : I use Python 3.3.4, mongoengine 0.8.7, Django 1.6.2 and mongodb 2.0.6

Loutre

unread,
Feb 25, 2014, 9:19:15 AM2/25/14
to django...@googlegroups.com
I realized that indexes have not been created by mongoengine :
db.author.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "poesie.author",
                "name" : "_id_"
        }
]

I'm still searching for a solution...

Loutre

unread,
Feb 25, 2014, 9:38:20 AM2/25/14
to django...@googlegroups.com
It works if I call insure_indexes() method. I can't understand why. Is there to avoid it ?

My code that works :


from django.test import TestCase
from les_classiques.models import Author
import mongoengine


class DatabaseTest(TestCase):
    def setUp(self):
        db = mongoengine.connection.get_db()
        for collection in db.collection_names(include_system_collections=False):
            db.drop_collection(collection)

    def test_insert_new_author(self):
        author = Author(name='Hugo', first_name='Victor')
        author.save()
        db_author = Author.objects(name='Hugo', first_name='Victor')[0]
        self.assertEqual(db_author.name, 'Hugo')

    def test_insert_duplicate_author_failure(self):
          Author.insure_indexes()
Reply all
Reply to author
Forward
0 new messages