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,并且相关查询不会添加到查询列表中。