问题描述
使用SQLAlchemy创建ORM模型后,会存在这样一类问题:
1.直接返回查询结果会存在 对象转json失败
TypeError: Object of type 'XXX' is not JSON serializable
2.返回对象中有一些字段我们不希望输出道接口中
eg: 用户模型中的 password 字段, 我们不希望这个字段存在于接口中
3.我们希望对一些特殊字段做一些特殊的处理
eg: 模型中的 datetime 字段,我们希望它在接口中呈现为 "%Y-%m-%d %H:%M:%S" 这种格式
问题分析
我们使用 SQLAlchemy
创建模型的时候,每个模型都要继承自 sqlalchemy.ext.declarative.declarative_base()
这个基类,因此我们可以在这个基类上注入一些特性来完成对象到字典的转换。
问题处理
models/__init__.py
...
def _to_dict(self):
"""
to dict
"""
d = {}
for c in self.__table__.columns:
if c.name not in self._hidden_not_safe:
val = getattr(self, c.name, None)
# 处理 datetime 格式化
if isinstance(val, datetime):
val = val.strftime("%Y-%m-%d %H:%M:%S")
d.update({
c.name: val
})
return d
# Model 基类
Base = declarative_base()
# do not show when convert it to dict
Base._hidden_not_safe = []
Base.to_dict = _to_dict
models/User.py
class User(Base):
__tablename__ = 'qt_user'
# 当需要隐藏某些字段时,只需要将要隐藏的字段加入下面列表中即可
# 如不重写本属性,则该模型的所有列都可见
_hidden_not_safe = ['password', 'delete_at']
...
控制器调用
...
user = conn.query(User).filter(and_(User.email==email, User.delete_at==None)).first()
data = user.to_dict() # to_dict 是挂载到 Base 类上面的方法,所有的模型类都继承了Base,所有都拥有了to_dict方法
return json.dumps(data)