关于python:Sqlalchemy-数据模型序列化转JSON

13次阅读

共计 1405 个字符,预计需要花费 4 分钟才能阅读完成。

Sqlalchemy 能够很不便地做 ORMapping,把数据库记录映射为业务实体类的实例,例如上面这样:

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    city = db.Column(db.String(50))
    addr = db.Column(db.String(200))
    pin = db.Column(db.String(10))


if __name__ == '__main__':
    student = Student.query.get(1)
    

但这种实例不不便序列化,比方要想在 Flask Web Service 接口中返回这个对象:

@app.route('/demo/db', methods=['GET'])
def demo_db():
    student = Student.query.get(1)
    return jsonify(student)

或者是间接转 JSON 字符串:

import json

json.dumps(student)

都会报错:Object of type Student is not JSON serializable

在网上搜的话,会有形形色色的答案,大部分都是让你实现某个相似 to_json 的办法,有些基本不论用,有些很麻烦。
其实 最简略的解决方案 就是:

用 python 3.7 引入的 dataclass 装璜器,这个装璜器帮咱们实现了对应的办法,能够间接把类变量申明当做实例变量的定义:

from dataclasses import dataclass


@dataclass
class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    city = db.Column(db.String(50))
    addr = db.Column(db.String(200))
    pin = db.Column(db.String(10))

这时候,再调用 jsonify(student) 就不会报错了,但奇怪的是,后果是个空对象:{}
原来 dataclass 装璜器“认可”的字段申明,必须有 type annotation,改成上面这样:

from dataclasses import dataclass


@dataclass
class Student(db.Model):
    id: int = db.Column(db.Integer, primary_key=True)
    name: str = db.Column(db.String(100))
    city: str = db.Column(db.String(50))
    addr: str = db.Column(db.String(200))
    pin: str = db.Column(db.String(10))

输入后果就完满了:

{
  addr: "xxx",
  city: "bj",
  id: 1,
  name: "hui",
  pin: "xyz"
}

不过 jsonify 尽管可用了,json.dumps仍然会报错,最简略的方法,是先把对象转为 dict,再转 json:

import json
from dataclasses import dataclass

print(json.dumps(dataclasses.asdict(student)))
正文完
 0