Сериализация SQLAlchemy с Зефир - PullRequest
0 голосов
/ 13 января 2020

Я следую учебному пособию и использую приведенный ниже код. Я также использую Почтальон для просмотра состояния сервера для http://localhost: 5000 / planets , но я получаю 500 ВНУТРЕННЯЯ ОШИБКА СЕРВЕРА, , когда я должен увидеть свой JSON данные о планетах, которые я создал. В командной строке я также вижу: AttributeError: у объекта 'list' нет атрибута 'data'

Я чувствую, что это может быть связано со строкой: return jsonify (result. данные) но я не уверен.

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()

1 Ответ

1 голос
/ 13 января 2020

Вместо

result = planets_schema.dump(planets_list)
return jsonify(result.data)

Попробуйте

result = planets_schema.dump(planets_list)
return jsonify(result)

Почему это работает:

Здесь вы запрашиваете Pl anet Mapper, чтобы вернуть список Pl anet 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)

Метод jsonify из flask принимает список словарей в качестве входных данных, поэтому простое изменение этой строки к приведенному ниже должно работать:

return jsonify(result)
...