用 Marshmallow 序列化 SQLAlchemy
Serializing SQLAlchemy with Marshmallow
我正在学习教程并使用以下代码。我也在使用 Postman 查看 http://localhost:5000/planets 的服务器状态,但是当我应该看到我的 JSON 时,我得到了 500 INTERNAL SERVER ERROR,我创建的行星的数据。
在命令行中我还看到:AttributeError: 'list' object has no attribute 'data'
我觉得这可能与以下行有关:return jsonify(result.data) 但我不确定。
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, Float
import os
from flask_marshmallow import Marshmallow
from marshmallow import Schema
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///C:/Users/krist/Py3/flask2/planets.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)
@app.cli.command('db_create')
def db_create():
db.create_all()
print("DB Created")
@app.cli.command('db_seed')
def deb_seed():
mercury = Planet(planet_name='Mercury',
planet_type='Class D',
home_star='Sol',
mass=3.25e23,
radius=1516,
distance=35.98e6)
venus = Planet(planet_name='Venus',
planet_type='Class K',
home_star='Sol',
mass=8.95e24,
radius=3516,
distance=67.98e6)
earth = Planet(planet_name='Earth',
planet_type='Class M',
home_star='Sol',
mass=5.97e24,
radius=3916,
distance=92.96e6)
db.session.add(mercury)
db.session.add(venus)
db.session.add(earth)
test_user = User(first_name='William',
last_name='Hershel',
email='test@test.com',
password='p@ssw0rd')
db.session.add(test_user)
db.session.commit()
print("DB Seeded")
@app.route('/planets', methods=['GET'])
def planets():
planets_list = Planet.query.all()
result = planets_schema.dump(planets_list)
return jsonify(result.data)
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
email = Column(String, unique=True)
password = Column(String)
class Planet(db.Model):
__tablename__ = 'planets'
planet_id = Column(Integer, primary_key=True)
planet_name = Column(String)
planet_type = Column(String)
home_star = Column(String)
mass = Column(Float)
radius = Column(Float)
distance = Column(Float)
class UserSchema(ma.Schema):
class Meta:
fields = ('id', 'first_name', 'last_name', 'email', 'password')
class PlanetSchema(ma.Schema):
class Meta:
fields = ('planet_id', 'planet_name', 'planet_type', 'home_star', 'mass', 'radius', 'distance')
user_schema = UserSchema()
users_schema = UserSchema(many=True)
planet_schema = PlanetSchema()
planets_schema = PlanetSchema(many=True)
if __name__ == '__main__':
app.run()
而不是
result = planets_schema.dump(planets_list)
return jsonify(result.data)
尝试
result = planets_schema.dump(planets_list)
return jsonify(result)
为什么这有效:
在这里,您正在查询 Planet Mapper return Planet ORM 对象列表
planets_list = Planet.query.all()
然后使用 Marshmallow 模式将 ORM 对象编组或转换为 python 字典对象。这就是编组的基本原理——在数据即将传输或存储时,将数据从一种格式转换为另一种格式。因此,在这种情况下,您将数据从 SQLAlchemy ORM 对象列表转换为 Python 字典对象列表。
result = planets_schema.dump(planets_list)
现在您有 result
(更恰当的是包含字典对象列表的名称 results
。
然后您正试图访问此列表对象上的 data
变量。但是 Python 列表没有 data
变量,所以你会得到一个错误。
return jsonify(result.data)
flask 中的 jsonify
方法接受字典列表作为输入,因此只需将这一行修改为以下内容即可:
return jsonify(result)
我正在学习教程并使用以下代码。我也在使用 Postman 查看 http://localhost:5000/planets 的服务器状态,但是当我应该看到我的 JSON 时,我得到了 500 INTERNAL SERVER ERROR,我创建的行星的数据。 在命令行中我还看到:AttributeError: 'list' object has no attribute 'data'
我觉得这可能与以下行有关:return jsonify(result.data) 但我不确定。
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, Float
import os
from flask_marshmallow import Marshmallow
from marshmallow import Schema
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///C:/Users/krist/Py3/flask2/planets.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)
@app.cli.command('db_create')
def db_create():
db.create_all()
print("DB Created")
@app.cli.command('db_seed')
def deb_seed():
mercury = Planet(planet_name='Mercury',
planet_type='Class D',
home_star='Sol',
mass=3.25e23,
radius=1516,
distance=35.98e6)
venus = Planet(planet_name='Venus',
planet_type='Class K',
home_star='Sol',
mass=8.95e24,
radius=3516,
distance=67.98e6)
earth = Planet(planet_name='Earth',
planet_type='Class M',
home_star='Sol',
mass=5.97e24,
radius=3916,
distance=92.96e6)
db.session.add(mercury)
db.session.add(venus)
db.session.add(earth)
test_user = User(first_name='William',
last_name='Hershel',
email='test@test.com',
password='p@ssw0rd')
db.session.add(test_user)
db.session.commit()
print("DB Seeded")
@app.route('/planets', methods=['GET'])
def planets():
planets_list = Planet.query.all()
result = planets_schema.dump(planets_list)
return jsonify(result.data)
class User(db.Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
first_name = Column(String)
last_name = Column(String)
email = Column(String, unique=True)
password = Column(String)
class Planet(db.Model):
__tablename__ = 'planets'
planet_id = Column(Integer, primary_key=True)
planet_name = Column(String)
planet_type = Column(String)
home_star = Column(String)
mass = Column(Float)
radius = Column(Float)
distance = Column(Float)
class UserSchema(ma.Schema):
class Meta:
fields = ('id', 'first_name', 'last_name', 'email', 'password')
class PlanetSchema(ma.Schema):
class Meta:
fields = ('planet_id', 'planet_name', 'planet_type', 'home_star', 'mass', 'radius', 'distance')
user_schema = UserSchema()
users_schema = UserSchema(many=True)
planet_schema = PlanetSchema()
planets_schema = PlanetSchema(many=True)
if __name__ == '__main__':
app.run()
而不是
result = planets_schema.dump(planets_list)
return jsonify(result.data)
尝试
result = planets_schema.dump(planets_list)
return jsonify(result)
为什么这有效:
在这里,您正在查询 Planet Mapper return Planet ORM 对象列表
planets_list = Planet.query.all()
然后使用 Marshmallow 模式将 ORM 对象编组或转换为 python 字典对象。这就是编组的基本原理——在数据即将传输或存储时,将数据从一种格式转换为另一种格式。因此,在这种情况下,您将数据从 SQLAlchemy ORM 对象列表转换为 Python 字典对象列表。
result = planets_schema.dump(planets_list)
现在您有 result
(更恰当的是包含字典对象列表的名称 results
。
然后您正试图访问此列表对象上的 data
变量。但是 Python 列表没有 data
变量,所以你会得到一个错误。
return jsonify(result.data)
flask 中的 jsonify
方法接受字典列表作为输入,因此只需将这一行修改为以下内容即可:
return jsonify(result)