Python flassger:获取具有扩展条件的查询? (更多,更少,介于...之间)
Python flassger: Get query with extended conditions ? (more, less, between...)
我开发了一个基于 flask 的 python 应用程序,它连接到 postgresql 数据库并使用 flassger(swagger UI)公开 API。
我已经定义了一个基本的 API(通过 ID 等处理条目)以及一个查询 api 来匹配不同的参数(例如 name=='John Doe')。
我想扩展此查询 api 以集成更复杂的查询,例如低于、高于、介于、包含等
我在互联网上搜索但找不到合适的方法。 有什么建议吗?
我发现这篇文章很有用,但没有说明查询的实现:https://hackernoon.com/restful-api-designing-guidelines-the-best-practices-60e1d954e7c9
这里是到目前为止的简要情况(一些提取的代码):
GET_query.xml:
Return an account information
---
tags:
- accounts
parameters:
- name: name
in: query
type: string
example: John Doe
- name: number
in: query
type: string
example: X
- name: opened
in: query
type: boolean
example: False
- name: highlighted
in: query
type: boolean
example: False
- name: date_opened
in: query
type: Date
example: 2018-01-01
蓝图定义:
ACCOUNTS_BLUEPRINT = Blueprint('accounts', __name__)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountQueryResource,
'/accounts/<query>',
endpoint='accountq'
)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountResource,
'/accounts/<int:id>',
endpoint='account'
)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountListResource,
'/accounts',
endpoint='accounts'
)
资源:
from flasgger import swag_from
from urllib import parse
from flask_restful import Resource
from flask_restful.reqparse import Argument
from flask import request as req
...
class AccountQueryResource(Resource):
""" Verbs relative to the accounts """
@staticmethod
@swag_from('../swagger/accounts/GET_query.yml')
def get(query):
""" Handle complex queries """
logger.debug('Recv %s:%s from %s', req.url, req.data, req.remote_addr)
query = dict(parse.parse_qsl(parse.urlsplit(req.url).query))
logger.debug('Get query: {}'.format(query))
try:
account = AccountRepository.filter(**query)
except Exception as e:
logger.error(e)
return {'error': '{}'.format(e)}, 409
if account:
result = AccountSchema(many=True).dump(account)
logger.debug('Get query returns: {}({})'.format(account, result))
return {'account': result}, 200
logger.debug('Get query returns: {}'.format(account))
return {'message': 'No account corresponds to {}'.format(query)}, 404
最后是存储库:
class AccountRepository:
""" The repository for the account model """
@staticmethod
def get(id):
""" Query an account by ID """
account = AccountModel.query.filter_by(id=id).first()
logger.debug('Get ID %d: got:%s', id, account)
return account
@staticmethod
def filter(**kwargs):
""" Query an account """
account = AccountModel.query.filter_by(**kwargs).all()
logger.debug('Filter %s: found:%s', kwargs, account)
return account
...
我不知道你的确切问题,但我遇到了与你类似的问题,我用以下方法修复了它:
query = []
if location:
query.append(obj.location==location)
我将使用
查询此查询列表
obj.query.filter(*query).all()
在上面的示例中,obj
是您创建的 model
的名称。
这个帮助如何?这将允许您动态填写您拥有的变量,并且每个查询都有自己的条件。您可以使用 ==
、!=
、<=
等
请注意,您应该使用 filter
而不是 filter_by
,然后您可以使用任意数量的运算符。
您可以阅读 link1 and link2 以获取有关如何查询 sqlalchemy 的文档。
编辑:
name = request.args.get("name")
address = request.args.get("address")
age = request.args.get("address")
query = []
if name:
query.append(Myobject.name==name)
if address:
query.append(Myobject.address==name)
if age:
query.append(Myobject.age >= age) # look how we select people with age over the provided number!
query_result = Myobject.query.filter(*query).all()
当用户没有提供任何值时,if
's 将帮助您。这样您就不会在主查询中包含这些查询。使用 get
,如果用户未提供这些值,则它们将为 None,并且相关查询不会添加到查询列表中。
我开发了一个基于 flask 的 python 应用程序,它连接到 postgresql 数据库并使用 flassger(swagger UI)公开 API。 我已经定义了一个基本的 API(通过 ID 等处理条目)以及一个查询 api 来匹配不同的参数(例如 name=='John Doe')。
我想扩展此查询 api 以集成更复杂的查询,例如低于、高于、介于、包含等
我在互联网上搜索但找不到合适的方法。 有什么建议吗?
我发现这篇文章很有用,但没有说明查询的实现:https://hackernoon.com/restful-api-designing-guidelines-the-best-practices-60e1d954e7c9
这里是到目前为止的简要情况(一些提取的代码):
GET_query.xml:
Return an account information
---
tags:
- accounts
parameters:
- name: name
in: query
type: string
example: John Doe
- name: number
in: query
type: string
example: X
- name: opened
in: query
type: boolean
example: False
- name: highlighted
in: query
type: boolean
example: False
- name: date_opened
in: query
type: Date
example: 2018-01-01
蓝图定义:
ACCOUNTS_BLUEPRINT = Blueprint('accounts', __name__)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountQueryResource,
'/accounts/<query>',
endpoint='accountq'
)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountResource,
'/accounts/<int:id>',
endpoint='account'
)
Api(ACCOUNTS_BLUEPRINT).add_resource(
AccountListResource,
'/accounts',
endpoint='accounts'
)
资源:
from flasgger import swag_from
from urllib import parse
from flask_restful import Resource
from flask_restful.reqparse import Argument
from flask import request as req
...
class AccountQueryResource(Resource):
""" Verbs relative to the accounts """
@staticmethod
@swag_from('../swagger/accounts/GET_query.yml')
def get(query):
""" Handle complex queries """
logger.debug('Recv %s:%s from %s', req.url, req.data, req.remote_addr)
query = dict(parse.parse_qsl(parse.urlsplit(req.url).query))
logger.debug('Get query: {}'.format(query))
try:
account = AccountRepository.filter(**query)
except Exception as e:
logger.error(e)
return {'error': '{}'.format(e)}, 409
if account:
result = AccountSchema(many=True).dump(account)
logger.debug('Get query returns: {}({})'.format(account, result))
return {'account': result}, 200
logger.debug('Get query returns: {}'.format(account))
return {'message': 'No account corresponds to {}'.format(query)}, 404
最后是存储库:
class AccountRepository:
""" The repository for the account model """
@staticmethod
def get(id):
""" Query an account by ID """
account = AccountModel.query.filter_by(id=id).first()
logger.debug('Get ID %d: got:%s', id, account)
return account
@staticmethod
def filter(**kwargs):
""" Query an account """
account = AccountModel.query.filter_by(**kwargs).all()
logger.debug('Filter %s: found:%s', kwargs, account)
return account
...
我不知道你的确切问题,但我遇到了与你类似的问题,我用以下方法修复了它:
query = []
if location:
query.append(obj.location==location)
我将使用
查询此查询列表obj.query.filter(*query).all()
在上面的示例中,obj
是您创建的 model
的名称。
这个帮助如何?这将允许您动态填写您拥有的变量,并且每个查询都有自己的条件。您可以使用 ==
、!=
、<=
等
请注意,您应该使用 filter
而不是 filter_by
,然后您可以使用任意数量的运算符。
您可以阅读 link1 and link2 以获取有关如何查询 sqlalchemy 的文档。
编辑:
name = request.args.get("name")
address = request.args.get("address")
age = request.args.get("address")
query = []
if name:
query.append(Myobject.name==name)
if address:
query.append(Myobject.address==name)
if age:
query.append(Myobject.age >= age) # look how we select people with age over the provided number!
query_result = Myobject.query.filter(*query).all()
当用户没有提供任何值时,if
's 将帮助您。这样您就不会在主查询中包含这些查询。使用 get
,如果用户未提供这些值,则它们将为 None,并且相关查询不会添加到查询列表中。