M
M
Max Payne2019-01-12 00:59:19
Python
Max Payne, 2019-01-12 00:59:19

How to logically match mongodb documents with project objects?

I have some entities, objects in my project, for example, the User class, the Chat class, and there are documents to which they are attached. Can I somehow extend the document object? That is, now, in order to manage only with the Chat class, I have to use such noodles, but all I just need to do is create a chat in the database, if it does not exist, and add one property method.

class Chat(Document):
    bot = ObjectIdField(required=True)
    i = LongField(required=True)
    greeting = BooleanField(default=True, required=True)
    rules = StringField(min_length=2)
    silence_ts = LongField(required=True)
    games = EmbeddedDocumentListField(Game)

    meta = {
        'indexes': [
            {"fields": ["bot", "i"], "unique": True}
        ]
    }

class Chat:
    def __init__(self, bot, i=0):
        self.bot = bot
        self.i = i

    def __getattr__(self, item):
        data = modules.Chat.objects(bot=self.bot.id, i=self.i)

        if not data:
            data = modules.Chat(bot=self.bot.id, i=self.i).save()
        else:
            data = data[0]

        return getattr(data, item)

    @property
    def is_silence(self):
        return self.silence_ts >= tools.ts()

And for this I pay the inability to update many values ​​on the fly. Account for instead
user = modules.User.objects.first()
# ...
user.balance += 1000

Make
user = User(bot, 1)
# ...
user.update(inc__balance=1000)

It only seems beautiful, but with large document structures, in this situation, you can simply die.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Max Payne, 2019-01-13
@YardalGedal

Found this solution for me.

class Chat:
    def __init__(self, bot, i=0):
        self._bot = bot

        data = modules.Chat.objects(bot=bot.id, i=i)

        if not data:
            self._data = modules.Chat(bot=bot.id, i=i).save()
        else:
            self._data = data[0]

    def __getattr__(self, item):
        self._data.reload()
        return getattr(self._data, item)

    def __setattr__(self, key, value):
        if key not in ('_data', '_bot'):
            data = self._data.__setattr__(key, value)
            self._data.save()
            return data
        else:
            return super().__setattr__(key, value)

But the problem remains: when the field is an EmbeddedDocumentListField, you cannot append / extend / pop and so on into it.

A
alternativshik, 2019-01-12
@alternativshik

user.balance += 1000
will probably be non-atomic and everything can go *out (although it is not known how your wrapper for mono works in this regard.)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question