0

I'm using mongoengine (http://mongoengine.org/) in a Django project. I don't know if this is such a good idea, but I thought I'd just try to get it work since there seems to be no up to date MongoDB implementation for Django. When running my server and trying to access localhost:8000/workoutcal/ I get this error:

Traceback (most recent call last):
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/workout/workoutcal/views.py", line 18, in calendar
    workouts_in_month = Workout.objects(Q(date__gte=datetime(year=today_year, month=today_month, day=today_day)) & Q(date__lt=datetime(year=today_year, month=today_month+1, day=1)))
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/mongoengine/queryset/manager.py", line 37, in __get__
    queryset = queryset_class(owner, owner._get_collection())
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/mongoengine/document.py", line 204, in _get_collection
    cls.ensure_indexes()
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/mongoengine/document.py", line 834, in ensure_indexes
    collection.create_index(fields, background=background, **opts)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/collection.py", line 1571, in create_index
    self.__create_index(keys, kwargs)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/collection.py", line 1472, in __create_index
    parse_write_concern_error=True)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/collection.py", line 232, in _command
    collation=collation)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/pool.py", line 477, in command
    collation=collation)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/network.py", line 116, in command
    parse_write_concern_error=parse_write_concern_error)
  File "/Users/sahandzarrinkoub/Documents/Programming/Web/Django/workout/lib/python3.6/site-packages/pymongo/helpers.py", line 203, in _check_command_response
    raise DuplicateKeyError(errmsg, code, response)
pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: db.workout index: id_1 dup key: { : null }

I have trouble understanding this error. Does it mean there's a duplicate key for the workout document? That sounds strange since this is what my workoutcal/models.py looks like:

from mongoengine import *

class Person(Document):
    name = StringField(max_length = 200)
    person_id = IntField(unique = True)
    def __str__(self):
        return str(self.person_id) + self.name

class Lift(EmbeddedDocument):
    lift_id = IntField(unique=True)
    name = StringField(max_length=200) #e.g. bench press, etc
    sets = ListField(IntField()) # No of reps in each set
    def __str__(self):
        return self.name

class Cardio(EmbeddedDocument):
    cardio_id = IntField(unique=True)
    name = StringField(max_length=200)
    duration = IntField() #Number of minutes
    distance = IntField() #Number of metres
    def __str__(self):
        return self.name

class Workout(Document):
    id = IntField(unique=True)
    date = DateTimeField()
    person = ReferenceField(Person)
    lifts = ListField(EmbeddedDocumentField(Lift))
    cardio = ListField(EmbeddedDocumentField(Cardio))
    def __str__(self):
        return str(self.date)+" "+self.person.name

Other info that might be useful:

I did not know where to do connect('db') (connecting to the mongod database on my computer) so I just put it in my settings.py:

from mongoengine import connect
...
connect('db') # <---
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # I kept this since it's needed for admin, etc.
        'NAME': 'mydatabase',
    }
}

workoutcal/urls.py:

app_name = 'workoutcal'
urlpatterns = [
    url(r'^$', views.calendar, name = 'calendar'),
    url(r'^(?P<id>[0-9]+)/$', views.detail, name = 'detail'), #Detail of a workout. Shows lifts, duration, etc. All the attributes.
    url(r'^add/(?P<year>[0-9]+)/(?P<month>[0-9]+)/(?P<day>[0-9]+)/$', views.add, name = 'add'), #Adding a workout for the date in question
    url(r'^edit/(?P<id>[0-9]+)/$', views.edit, name = 'edit'), #Editing an existing workout. id is id of workout object to edit.
]

In short, my questions are:

  1. Why am I getting this error and what can I do about it?
  2. What is the correct what to connect() to the mongod in my Django project?
  3. Your thoughts about integrating mongoenging with django in this way?
0

1 Answer 1

1

duplicate key error collection: db.workout index: id_1 dup key: { : null } means in mongo that you have stored a workout entity with id = null and now are trying to store another workout entity with id = null. You will have to clean up the db manually. After that, take a look at

class Workout(Document):
    id = IntField(unique=True)

The id is not required, so I suppose you do not have it set when saving entities to database. Add null=False to the id field parameters to ensure it is initialized. Or even better, do not have an id field at all and let django autocreate one for you - not sure though, how it works out with mongo.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer. One question: You say that I should clean the database manually I assume you mean clean it of documents in db.workout (a collection) with id=null. The thing is: I get this output when examining the collection: > db.workout.find() { "_id" : ObjectId("59ba9a56aba92f063ee577af"), "date" : ISODate("2017-09-14T14:58:02.984Z"), "person" : ObjectId("59ba9a4daba92f063ee577ae"), "lifts" : [ { "name" : "bench press", "sets" : [ 3, 4 ] }, { "name" : "squat", "sets" : [ 3, 4 ] } ], "cardio" : [ { "name" : "running", "duration" : 10, "distance" : 800 } ] }
and then another 3 documents that look similar to that. The interesting thing is, none of them have "_id" : null. If no document has id=null, how can there be a duplicate key null?
Hmm, try recreating the indexes then.
I ran db.workout.reIndex(), and while it solved this error, it created another one: mongoengine.errors.FieldDoesNotExist: The fields "{'_id'}" do not exist on the document "Workout". What does this mean?
And actually, upon rehosting the server, the original error came back...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.