我正在使用flask_restplus
和flask_sqlalchemy
开发API,但我有一个特殊情况,即某些应用程序应仅访问API中的某些列。
我有一个模特:
class MyModel(db.Model):
__tablename_ = 'my_table'
id = db.Column(db.Integer, primary_key=True)
first_column = db.Column(db.Unicode)
second_column = db.Column(db.Unicode)
我还指定了要从API返回的flask_resplus
'模型:
my_model = api.model('MyModel',
{'first_column': fields.String(),
'second_column': fields.String()})
其中api
是flask_restplus
'Api
的实例,db
是flask_sqlachmey
的实例。
有时候,我只想选择一些列,而另一列要作为以JSON响应返回的null
中的api.model
。
在Internet上搜索后,我发现两种方法都不适合我的情况:
load_only()
中的sqlalchemy.orm
,将列返回为list
。结果,我无法返回这些结果,因为我的模型期望字典具有与my_model
中所述相同的键。另一种方法with_entities()
返回我需要的MyModel
实例,但是在我将该实例传递给my_model
时它会加载所有列,因为它只会惰性选择,即它选择指定的列,但是如果需要其他列,它会再次执行查询以获取其他列的值,因此在我的情况下,加载所有列,这不是我想要的。
有人知道如何做SQL SELECT
,其中仅返回一些列,结果是db.Model
的实例?
提前谢谢!
答案 0 :(得分:1)
您可以在flask-restplus中使用“字段屏蔽”来仅访问所需的字段。
签出此链接:https://flask-restplus.readthedocs.io/en/stable/mask.html
curl -X GET "http://localhost:5000/mymodel" -H "accept: application/json" -H "X-Fields: first_column"
from flask import Flask
from flask_restplus import Resource, Api
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String
import os
from flask_restplus import Resource, fields
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{0}/app-dev.db'.format(
basedir)
app.config['SECRET_KEY'] = '\xa4?\xca`\xa4~zG\xdf\xdbh\xba\xc2\xc6\xfc\x88\xc6x"\x11\xe8X8\n'
db = SQLAlchemy(app)
api = Api(app)
class MyModel(db.Model):
__tablename_ = 'my_table'
id = db.Column(db.Integer, primary_key=True)
first_column = db.Column(db.String(255))
second_column = db.Column(db.String(255))
my_model = api.model('MyModel',
{'first_column': fields.String(),
'second_column': fields.String()})
@api.route('/mymodel')
class GetModel(Resource):
@api.marshal_with(my_model, envelope='resource', mask='first_column')
def get(self, **kwargs):
return MyModel.query.all() # Some function that queries the db
@api.route('/hello')
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
if __name__ == '__main__':
db.drop_all()
db.create_all()
model1 = MyModel(first_column='m1_first', second_column='M1_SECOND')
model2 = MyModel(first_column='m2_first', second_column='M2_SECOND')
db.session.add(model1)
db.session.add(model2)
db.session.commit()
app.run(debug=True)
答案 1 :(得分:1)
如果使用flask-marshmallow进行序列化,则可以使用包含(only()
)或排除(load_only()
)字段的列表加载架构。
因此,您可以粗略地模拟上面的内容:
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
db = SQLAlchemy()
ma = Marshmallow()
class MyModel(db.Model):
__tablename_ = 'my_table'
id = db.Column(db.Integer, primary_key=True)
first_column = db.Column(db.Unicode)
second_column = db.Column(db.Unicode)
class MyModelSchema(ma.ModelSchema):
class Meta:
model = MyModel
varlist = ['id','first_column']
def somefunction():
results = MyModel.query.all()
mymodelschema = MyModelSchema(many=True, only=varlist)
output = mymodelschema.dump(results).data
return jsonify(output) # or whatever you're doing with it
以下是棉花糖模式API的文档,其中有一些选项,包括排除列表中的所有内容,例如:https://marshmallow.readthedocs.io/en/latest/api_reference.html#marshmallow.Schema