tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.68k stars 390 forks source link

fix: check attr exists before setattr to aviod KeyError #1416

Open ezioruan opened 1 year ago

ezioruan commented 1 year ago

Description

After the service has been running for a period of time, the tortoise orm will suddenly report an error and need to restart the service to repair it.

Additional context Add any other context about the problem here.

Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/tortoise/models.py", line 717, in _init_from_db setattr(self, model_field, kwargs[key]) KeyError: 'images'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/data/frontend/api.py", line 3296, in viewRecord scheme_obj = await Scheme.get_or_none(uni_id=scheme_id) File "/usr/local/lib/python3.8/dist-packages/tortoise/queryset.py", line 908, in _execute instance_list = await self._db.executor_class( File "/usr/local/lib/python3.8/dist-packages/tortoise/backends/base/executor.py", line 134, in execute_select instance: "Model" = self.model._init_from_db( File "/usr/local/lib/python3.8/dist-packages/tortoise/models.py", line 734, in _init_from_db setattr(self, key, meta.fields_map[key].to_python_value(value)) KeyError: 'watch_user_id' Traceback (most recent call last): File "/data/frontend/api.py", line 1446, in schemeList s['sale_num'] = await Order.filter(scheme_id=s['uni_id'], status=1).count() File "/usr/local/lib/python3.8/dist-packages/tortoise/queryset.py", line 1174, in _execute count = list(dict(result[0]).values())[0] - self.offset IndexError: list index out of range Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/tortoise/models.py", line 717, in _init_from_db setattr(self, model_field, kwargs[key]) KeyError: 'nickname'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/data/frontend/api.py", line 474, in getSubscribe wx_user_obj = await WXUserInfo.get_or_none(user_id=request.ctx.uid, app_id=ACTIVE_WX_APP_ID) File "/usr/local/lib/python3.8/dist-packages/tortoise/queryset.py", line 908, in _execute instance_list = await self._db.executor_class( File "/usr/local/lib/python3.8/dist-packages/tortoise/backends/base/executor.py", line 134, in execute_select instance: "Model" = self.model._init_from_db( File "/usr/local/lib/python3.8/dist-packages/tortoise/models.py", line 734, in _init_from_db setattr(self, key, meta.fields_map[key].to_python_value(value)) KeyError: 'COUNT(*)' Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/tortoise/models.py", line 717, in _init_from_db setattr(self, model_field, kwargs[key]) KeyError: 'user_id'

Motivation and Context

Check the attr exists before setting the attr to avoid the KeyError from the error stack we can see there's some key name "Count(*)". it should not be the attr for a model

How Has This Been Tested?

Checklist:

ggjkb22 commented 1 year ago

After completing this change, the queryset will report a KeyError again. I tried to avoid this error by reducing the version, but versions such as 0.19.3 and 0.18.1 all have this issue

ezioruan commented 1 year ago

can you share you error stack? @ggjkb22

ggjkb22 commented 1 year ago

Similar to your error stack, do you no longer report errors after the above modifications? @ezioruan

ezioruan commented 1 year ago

@long2ice could you help review?

long2ice commented 1 year ago

Can you show your code? This change maybe just avoid it but not fix it.

ezioruan commented 1 year ago

yes. But I don't know how to fix it. do you have any idea @long2ice