Автоинкремент с MongoEngine

Я разрабатываю движок блога с помощью Flask и MongoEngine, и мне нужны последовательные идентификаторы для моих сообщений.

Мне нужно, чтобы MongoEngine создавал новый идентификатор для каждого нового сообщения, поэтому я подумал сделать что-то вроде этого:

class Post(Document):
  title = StringField(required=True)
  content = StringField(required=True)
  published_at = datetime.utcnow()
  id = Post.objects.count() + 1

Будет ли это работать? Есть лучший способ сделать это?


person Mahmoud Hanafy    schedule 11.02.2012    source источник


Ответы (2)


Во-первых, вам нужно понять, зачем вам нужны инкрементные идентификаторы? Что они решают?

В mongoDB нет собственного решения — пожалуйста, прочитайте: http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field

Поскольку у вас уже есть уникальный идентификатор с pk сообщения, почему бы не использовать его?

Наконец, если я не отговорил вас от глупости, в mongoengine есть SequenceField, который обрабатывает увеличение за вас. https://mongoengine-odm.readthedocs.org/en/latest/apireference.html#mongoengine.fields.SequenceField

person Ross    schedule 13.02.2012
comment
Мне нужны дополнительные идентификаторы для сообщений, а также для пользователей, автоматически сгенерированные идентификаторы не подходят для использования в URL-адресах, поэтому я хочу создать свой собственный. - person Mahmoud Hanafy; 14.02.2012
comment
Конечно, но вы можете сделать удобочитаемые слаги - таким образом это также улучшит доступность URL-адресов. - person Ross; 14.02.2012
comment
SequenceField — единственная и лучшая реализация автоинкремента в Mongoengine. - person hamidfzm; 13.11.2014

Изменить: это неправильное решение, так как другие указали, что такой подход вызывает состояние гонки. Я только оставил это здесь, чтобы другие знали, почему это плохо. (несколько клиентов могут обращаться к одному и тому же объекту и увеличивать его, что приводит к противоречивым результатам).


Старый ответ:

Я понял.

Класс Post выглядит так:

class Post(Document):
      title = StringField(required=True)
      content = StringField(required=True)
      published_at = datetime.utcnow()
      ID = IntField(min_value=1)

И в функции, которая вставляет сообщение, я подсчитываю доступные записи, а затем увеличиваю их на 1, например:

def create_post(title, content):
      Post(title=title, content=content, ID=Post.objects.count() + 1).save()
person Mahmoud Hanafy    schedule 11.02.2012
comment
Махмуд - это неправильное решение, оно содержит состояние гонки и поэтому может потерпеть неудачу. - person Ross; 13.02.2012