python-gino / gino

GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core.
https://python-gino.org/
Other
2.68k stars 150 forks source link

Does Gino support prived params? #686

Closed semenovsd closed 4 years ago

semenovsd commented 4 years ago

Description

Trying apply to db ririved param:

class User(db.Model):
    __tablename__ = 'users'
    query: sql.Select

    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    __withdraw_details = Column(JSON, nullable=False, server_default="{}")

What I Did

    async def save_withdraw_data(self, data):
        data = {'fullname': str(data['fullname']).lower(),
                'phone_number': int(data['phone_number']),
                'email': str(data['email']).lower(),
                'passport_number': int(data['passport_number'])
                }
        await self.update(__withdraw_details=json.dumps(data)).apply()

Error: tgbot | web_protocol.py [LINE:355] #ERROR [2020-05-27 18:48:48,881] Error handling request tgbot | Traceback (most recent call last): tgbot | File "/usr/local/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 418, in start tgbot | resp = await task tgbot | File "/usr/local/lib/python3.8/site-packages/aiohttp/web_app.py", line 458, in _handle tgbot | resp = await handler(request) tgbot | File "/usr/local/lib/python3.8/site-packages/aiohttp/web_urldispatcher.py", line 892, in _it er tgbot | resp = await method() tgbot | File "/usr/local/lib/python3.8/site-packages/aiogram/dispatcher/webhook.py", line 140, in po st tgbot | results = await self.process_update(update) tgbot | File "/usr/local/lib/python3.8/site-packages/aiogram/dispatcher/webhook.py", line 191, in pr ocess_update tgbot | return fut.result() tgbot | File "/usr/local/lib/python3.8/site-packages/aiogram/dispatcher/handler.py", line 117, in no tify tgbot | response = await handler_obj.handler(*args, *partial_data) tgbot | File "/usr/local/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 229, in process_update tgbot | return await self.callback_query_handlers.notify(update.callback_query) tgbot | File "/usr/local/lib/python3.8/site-packages/aiogram/dispatcher/handler.py", line 117, in no tify tgbot | response = await handler_obj.handler(args, partial_data) tgbot | File "/APP_BASE_DIR/handlerssubscriber.py", line 223, in approve_edit_withdraw tgbot | await user.save_withdraw_data(data) tgbot | File "/APP_BASE_DIR/database.py", line 51, in save_withdraw_data tgbot | await self.update(__withdraw_details=json.dumps(data)).apply() tgbot | File "/usr/local/lib/python3.8/site-packages/gino/crud.py", line 596, in _update tgbot | return self._update_request_cls(self).update(values) tgbot | File "/usr/local/lib/python3.8/site-packages/gino/crud.py", line 225, in update tgbot | value = getattr(self._instance, value_from)[key] tgbot | KeyError: '__withdraw_details'

wwwjfy commented 4 years ago

This is a Python "feature": https://docs.python.org/3/tutorial/classes.html#private-variables

In your case, the name is actually _User__withdraw_details.

From my point of view, a model class should exhibit whatever it is in database. If this is something we don't want to expose, we can have a wrapper of the model. And in Python, there is no real "private" property outsiders can't access.

semenovsd commented 4 years ago

You are right! Thanks for help! with _User__withdraw_details it's working fine.

On the subject of private attributes, you are also right, I'm just still learning python and experimenting and trying out different features of objects.