用棉花糖序列化SQLAlchemy [英] Serializing SQLAlchemy with Marshmallow

查看:186
本文介绍了用棉花糖序列化SQLAlchemy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习一个教程,并使用下面的代码.我还使用Postman查看 http://localhost:5000/planets 的服务器状态,但是当我应该看到我创建的行星的JSON数据时,出现 500内部服务器错误. 在命令行中,我还看到: AttributeError:'list'对象没有属性'data'

I'm following a tutorial and using the below code. I'm also using Postman to view the status of the server for http://localhost:5000/planets , but I'm getting 500 INTERNAL SERVER ERROR, when I should see my JSON data of the planets I created. In the command line I also see: AttributeError: 'list' object has no attribute 'data'

我认为这可能与以下行有关:return jsonify(result.data),但我不确定.

I feel it might have to do with the line that has: return jsonify(result.data) but I'm not sure.

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,以返回Planet ORM对象的列表

Here you are querying the Planet Mapper to return a list of Planet ORM objects

planets_list = Planet.query.all()

然后,棉花糖模式用于封送或将ORM对象转换为python字典对象.这是封送处理的基本原理-当数据将要传输或存储时,将数据从一种格式转换为另一种格式.因此,在这种情况下,您可以将数据从SQLAlchemy ORM对象列表转换为Python字典对象列表.

Then the Marshmallow schema is used to marshal, or transform the ORM object into a python dictionary object. This is the basic principle of marshaling - transforming data from one format into another when the data is about to be transmitted or stored. So in this case you transform you data from a list of SQLAlchemy ORM objects into a list of Python dictionary objects.

result = planets_schema.dump(planets_list)

现在您有了result(可以更恰当地是包含字典对象列表的名称results. 然后,您尝试访问此列表对象上的data变量.但是,Python列表没有data变量,因此会出现错误.

Now you have result (which could more aptly be names results that contains a list of dictionary objects. Then you are attempting to access the data variable on this list object. However Python lists have no data variable, so you get an error.

return jsonify(result.data)

flask的jsonify方法接受字典列表作为输入,因此只需将此行修改为以下内容即可:

The jsonify method from flask accepts a list of dictionaries as input, so simply modifying this line to the below should work:

return jsonify(result)

这篇关于用棉花糖序列化SQLAlchemy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆