【发布时间】:2020-11-11 17:43:53
【问题描述】:
我正在尝试制作一个烧瓶 api(这对我来说是新领域),但我对返回数据的方式不满意。
它可以工作并连接到数据库并返回数据(耶),但它是一个字典列表(嘘)。
我想重新格式化它,所以当它被调用时,它看起来会有所不同。
烧瓶型号:
from flask import Flask, jsonify
from flask_restful import Api, Resource, reqparse, abort, fields, marshal_with
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
api = Api(app)
app.config["SQLALCHEMY_DATABASE_URI"] = 'postgres://postgres:[password]@127.0.0.1:5432/usagestats'
db = SQLAlchemy(app)
class StatsModel(db.Model):
#added in from edit1
def __getitem__(self, key):
return self.__dict__[key]
__tablename__ = "smogon_usage_stats"
id_ = db.Column(db.Integer, primary_key=True)
rank = db.Column(db.Integer, nullable=False)
pokemon = db.Column(db.String(50), nullable=False)
usage_pct = db.Column(db.Float, nullable=False)
raw_usage = db.Column(db.Integer, nullable=False)
raw_pct = db.Column(db.Float, nullable=False)
real = db.Column(db.Integer, nullable=False)
real_pct = db.Column(db.Float, nullable=False)
dex = db.Column(db.Integer, nullable=False)
date = db.Column(db.String(10), nullable=False)
tier = db.Column(db.String(50), nullable=False)
def __repr__(self):
return f"Stats(id = {id_}, rank = {rank}, pokemon = {pokemon}, usage_pct = {usage_pct}, raw_usage = {raw_usage}, raw_pct = {raw_pct}, real = {real}, real_pct = {real_pct})"
resource_fields = {
'id_': fields.Integer,
'rank': fields.Integer,
'pokemon': fields.String,
'usage_pct': fields.Float,
'raw_usage': fields.Integer,
'raw_pct': fields.Float,
'real': fields.Integer,
'real_pct': fields.Float,
'dex': fields.Integer,
'date': fields.String,
'tier': fields.String
}
class Stats(Resource):
@marshal_with(resource_fields)
def get(self, date, tier):
result = StatsModel.query.filter_by(date=date, tier=tier + "-1500").all()
return result
api.add_resource(Stats, "/stats/<string:date>/<string:tier>-1500")
if __name__ == "__main__":
app.run(host='127.0.0.1', port=3000, debug=True)
调用时返回如下:
[
{'id_': 669551, 'rank': 153, 'pokemon': 'snorunt', 'usage_pct': 0.07347, 'raw_usage': 104, 'raw_pct': 0.127, 'real': 96, 'real_pct': 0.148, 'dex': 361, 'date': '2020-04', 'tier': 'gen8lc-1500'},
{'id_': 669552, 'rank': 154, 'pokemon': 'milcery', 'usage_pct': 0.0672, 'raw_usage': 108, 'raw_pct': 0.131, 'real': 87, 'real_pct': 0.134, 'dex': 868, 'date': '2020-04', 'tier': 'gen8lc-1500'},
{'id_': 669553, 'rank': 156, 'pokemon': 'cosmog', 'usage_pct': 0.0199, 'raw_usage': 26, 'raw_pct': 0.032, 'real': 19, 'real_pct': 0.029, 'dex': 789, 'date': '2020-04', 'tier': 'gen8lc-1500'}
]
但我希望它看起来像这样:
{
"data":
'snorunt': {
'id_': 669551, 'rank': 153, 'pokemon': 'snorunt', 'usage_pct': 0.07347, 'raw_usage': 104, 'raw_pct': 0.127, 'real': 96, 'real_pct': 0.148, 'dex': 361, 'date': '2020-04', 'tier': 'gen8lc-1500'},
'milcery': {
'id_': 669552, 'rank': 154, 'pokemon': 'milcery', 'usage_pct': 0.0672, 'raw_usage': 108, 'raw_pct': 0.131, 'real': 87, 'real_pct': 0.134, 'dex': 868, 'date': '2020-04', 'tier': 'gen8lc-1500'},
'cosmog': {
'id_': 669553, 'rank': 156, 'pokemon': 'cosmog', 'usage_pct': 0.0199, 'raw_usage': 26, 'raw_pct': 0.032, 'real': 19, 'real_pct': 0.029, 'dex': 789, 'date': '2020-04', 'tier': 'gen8lc-1500'
}
}
我尝试在Stats 类中操作result,但它会引发错误(我已经将其取出,但这是不可迭代的错误)。我想我总是可以用我的 webapp 代码更改数据,但我宁愿把它打包并准备好。
编辑 1
所以我找到了一些解决方案,但还没有什么效果。
为了使对象可下标,我将其添加到模型中:
def __getitem__(self, key):
return self.__dict__[key]
__tablename__ = "smogon_usage_stats"
并制作了Stats类的get函数返回语句:
return {"data": {x["pokemon"]: x for x in result}}
但这只给了我一个输出。我猜这是技术上的改进。 (在尝试以下建议的答案时也得到了相同的结果
编辑 2
如果我可能遗漏了某些东西并且不再尝试对一行进行花哨,我尝试简化它,它仍然给我一个单一的输出。我已经验证result 是一个长度为143 的列表。但由于某种原因,我没有得到我想要的结果,而且我的空域和想法都用完了。
class Stats(Resource):
@marshal_with(resource_fields)
def get(self, date, tier):
result = StatsModel.query.filter_by(date=date, tier=tier + "-1500").all()
resp = {"data":{}}
for i in range(len(result)):
t = {result[i]["pokemon"]: result[i]}
resp["data"].update(t)
return resp
当我发出请求时会返回这个:
{
'id_': 0,
'rank': 0,
'pokemon': None,
'usage_pct': None,
#... to save space but you get the idea
'tier': None
}
另外,为了确定,我对迭代对象进行了type() 检查,它们返回了<class '__main__.StatsModel'>。
【问题讨论】:
标签: python json flask request flask-sqlalchemy