我是Flask和SQLAlchemy的新手,我花了很多时间尝试使用Flask url(不是flask_restful)使数据库查询以JSON形式显示。

我以为我可以通过使用n0nSmoker/SQLAlchemy-serializer来工作。它使用以下语法,通过选择我的Trade SQLAlchemy类的简单查询来工作:

trades = Trade.query.all()

我能够毫无问题地返回trades.to_dict()。

但是,由于我需要执行group_by,因此我需要使用db.session.query(Trade, Trade.exchange, Trade.trader.......等更灵活的语法,该方法停止了工作。

我已经查看了其他选项,例如检查系统,但它似乎超出了我的技能水平。另外,似乎像_asdict()之类的某些方法在行级别上不可用。

我有点迷茫,不知道如何进行。任何帮助将不胜感激。

编辑:请求更多代码:
app.py的顶部

from flask import Flask
from flask_restful import Resource, Api
from models import *
from flask_sqlalchemy import SQLAlchemy
from sqlathanor import FlaskBaseModel, initialize_flask_sqlathanor

app = Flask(__name__)
app.config.from_pyfile('config.py')

db = SQLAlchemy(model_class = FlaskBaseModel)
db = initialize_flask_sqlathanor(db)

class Trades(Resource):
    def get(self):
        return AllTrades()

api.add_resource(Trades,'/')


if __name__ == '__main__':
    app.run(host="0.0.0.0")


来自models.py

from app import db

class Trade(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    exchange = db.Column(db.String(255))
    trader = db.Column(db.String(255))
    symbol = db.Column(db.String(255))
    coin = db.Column(db.String(255))
    order_id = db.Column(db.String(255))
    price = db.Column(db.String(255))
    qty = db.Column(db.String(255))
    fee = db.Column(db.String(255))
    fee_currency = db.Column(db.String(255))
    order_time = db.Column(db.DateTime(timezone=False))
    side = db.Column(db.String(255))
    maker_taker = db.Column(db.String(255))


def AllTrades():
    #t = Trade
    # trades = db.session.query(
    #   t,
    #   t.exchange,
    #   t.trader,
    #   t.symbol,
    #   t.coin,
    #   db.func.sum(t.qty),
    #   db.func.sum(t.fee).label("fee"),
    #   t.fee_currency,
    #   t.order_id,
    #   t.order_time,
    #   t.maker_taker
    # ).group_by(t.order_id).all()

    trades = Trade.query.all()
    trades = trades.to_json()

    return trades


全栈跟踪

    Traceback (most recent call last):
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/_compat.py", line 32, in reraise
    raise value.with_traceback(tb)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/_compat.py", line 32, in reraise
    raise value.with_traceback(tb)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_restful/__init__.py", line 480, in wrapper
    resp = resource(*args, **kwargs)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask/views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_restful/__init__.py", line 595, in dispatch_request
    resp = meth(*args, **kwargs)
  File "/Users/foo/Sites/Reporting_dev/app.py", line 18, in get
    return AllTrades()
  File "/Users/foo/Sites/Reporting_dev/models.py", line 42, in AllTrades
    trades = Trade.query.all()
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 514, in __get__
    return type.query_class(mapper, session=self.sa.session())
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/sqlalchemy/orm/scoping.py", line 74, in __call__
    return self.registry()
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/sqlalchemy/util/_collections.py", line 1001, in __call__
    return self.registry.setdefault(key, self.createfunc())
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 2939, in __call__
    return self.class_(**local_kw)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 143, in __init__
    bind = options.pop('bind', None) or db.engine
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 877, in engine
    return self.get_engine()
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 887, in get_engine
    state = get_state(app)
  File "/Users/foo/anaconda3/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 570, in get_state
    'The sqlalchemy extension was not registered to the current ' \
AssertionError: The sqlalchemy extension was not registered to the current application.  Please make sure to call init_app() first.

最佳答案

我建议您看一两个星期前发布的新库,名为SQLAthanor

它为SQLAlchemy模型添加了简单的序列化支持,并且如果您还使用Flask-SQLAlchemy,那么它也可以无缝地工作。

基本上,它的工作方式是这样的:


您可以(大概)已经定义了Trade模型。唯一的区别是您从SQLAthanor而不是从SQLAlchemy(或Flask-SQLAlchemy)导入declarative_base或基本模型。
您可以在定义模型时配置序列化规则。这基本上可以让您说“当我将交易序列化为JSON时,包括属性X,Y和Z,但不包括P,D和Q”。
执行查询,但是通常会执行。您大概会得到一个Trade实例的列表。现在,您可以通过调用<instance>.to_json()将每个实例序列化为JSON。


值得一提的是SQLAthanor:


支持与JSON,CSV,YAML和Python dict之间的序列化和反序列化
支持Column属性,关系,混合属性,关联代理和常规Python @properties的序列化/反序列化
支持在属性级别进行序列化/反序列化的自定义预处理/后处理功能(用于验证或类型强制)
支持在属性级别为特定格式启用/禁用序列化和反序列化(例如,接受入站密码,但从不包括入站密码)


可能值得一看。这里是(希望全面)文档的链接:http://sqlathanor.readthedocs.io/en/latest/

希望对您有所帮助,如果您有任何疑问或需要帮助以使其正常运行,请告诉我(或使用标签sqlathanor将问题发布到SO)

关于python - Flask + SQLAlchemy结果转换为JSON,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51477961/

10-13 05:47