jsonfix3
All checks were successful
Deploy on push / deploy (push) Successful in 56s

This commit is contained in:
Untone 2025-03-20 12:52:44 +03:00
parent dbbfd42e08
commit b63c387806
3 changed files with 36 additions and 1 deletions

View File

@ -1,3 +1,8 @@
#### [0.4.13] - 2025-03-20
- Fixed Topic objects serialization error in cache/memorycache.py
- Improved CustomJSONEncoder to support SQLAlchemy models with dict() method
- Enhanced error handling in cache_on_arguments decorator
#### [0.4.12] - 2025-03-19 #### [0.4.12] - 2025-03-19
- `delete_reaction` detects comments and uses `deleted_at` update - `delete_reaction` detects comments and uses `deleted_at` update
- `check_to_unfeature` etc. update - `check_to_unfeature` etc. update

11
cache/memorycache.py vendored
View File

@ -99,10 +99,21 @@ class RedisCache:
try: try:
import asyncio import asyncio
# Попытка сериализовать результат в JSON
try:
serialized = json.dumps(result, cls=CustomJSONEncoder) serialized = json.dumps(result, cls=CustomJSONEncoder)
except (TypeError, ValueError) as e:
logger.debug(f"JSON сериализация не удалась, используем pickle: {e}")
# Если не удалось сериализовать как JSON, используем pickle
serialized = pickle.dumps(result).decode()
asyncio.create_task(redis.set(key, serialized, ex=self.ttl)) asyncio.create_task(redis.set(key, serialized, ex=self.ttl))
except Exception as e: except Exception as e:
logger.error(f"Ошибка при кешировании результата: {e}") logger.error(f"Ошибка при кешировании результата: {e}")
# Для отладки добавляем информацию о типе объекта
logger.debug(f"Тип результата: {type(result)}")
if hasattr(result, "__class__"):
logger.debug(f"Класс результата: {result.__class__.__name__}")
return result return result

View File

@ -3,7 +3,26 @@ from json import JSONEncoder
class CustomJSONEncoder(JSONEncoder): class CustomJSONEncoder(JSONEncoder):
"""
Расширенный JSON энкодер с поддержкой сериализации объектов SQLAlchemy.
Примеры:
>>> import json
>>> from decimal import Decimal
>>> from orm.topic import Topic
>>> json.dumps(Decimal("10.50"), cls=CustomJSONEncoder)
'"10.50"'
>>> topic = Topic(id=1, slug="test")
>>> json.dumps(topic, cls=CustomJSONEncoder)
'{"id": 1, "slug": "test", ...}'
"""
def default(self, obj): def default(self, obj):
if isinstance(obj, Decimal): if isinstance(obj, Decimal):
return str(obj) return str(obj)
# Проверяем, есть ли у объекта метод dict() (как у моделей SQLAlchemy)
if hasattr(obj, "dict") and callable(obj.dict):
return obj.dict()
return super().default(obj) return super().default(obj)