当flask应用程序启动时,如何使用从DB获取的数据作为add_argument()中的值? 数据.py控制器.py

问题描述

对于使用 flask

flask-restx 应用,我有以下项目结构
.
├── app
│   ├── extensions.py
│   ├── __init__.py
│   └── pv_dimensioning
│       ├── controller.py
│       ├── __init__.py
│       ├── models
│       │   ├── dto.py
│       │   ├── __init__.py
│       │   └── vendor_models.py
│       ├── services
│       │   ├── calculator.py
│       │   ├── database.py
│       │   ├── data.py
│       │   ├── db_crud.py
│       │   ├── __init__.py
│       │   └── processor.py
│       └── utils
│           ├── decode_verify_jwt.py
│           ├── decorator.py
│           └── __init__.py
├── config.py
├── main.py
├── package.json
├── package-lock.json
├── Pipfile
├── Pipfile.lock
├── README.md
├── serverless.yml
└── tests
    ├── __init__.py
    ├── test_calculator.py
    ├── test_config.py
    └── test_processor.py

controller.py 中,我添加add_argument() 语句并在 api 路由中解析它们。在 add_argument() 语句之一中,我想为用户添加 choices。为了获得选择,我从数据库查询获取可用值的 list。然后我将此 list 转换为 tuple,将其分配给变量,并将其作为 choices 参数传递给 add_argument()

我的代码

data.py

from ..models.vendor_models import Adminvendor

def data(app):
    values = Adminvendor.query.all()
    v = [value.name for value in values]
    return {'v': tuple(v)}

controller.py

from flask_restx import Resource,reqparse

parser = reqparse.RequestParser()

parser.add_argument(
    "vendor",choices=vendors,# <--- The values of v should be added here
    help="Select the vendor"
)

@ns.route("/")
class UserOutput(Resource):
    @ns.doc(
        "Get calculated response",responses={
            200: "Values returned",400: "Validation Error",403: "Not authorized"
        },)
    @ns.expect(parser,validation=True)
    def get(self):
        args = parser.parse_args()
        return Dimensioncalculator.inputs(**args),200

其中 nsnamespace

我在 __init__.py 文件夹中的 app 文件如下:

from flask import Flask

from .extensions import cors,db,ma

def create_app(app_config):
    app = Flask(__name__)

    app.config.from_object(app_config)

    register_blueprints(app)
    register_extensions(app)
    return app

def register_extensions(app):
    cors.init_app(app)
    db.init_app(app)
    ma.init_app(app)

def register_blueprints(app):
    from .pv_dimensioning import dimensioning_blueprint
    app.register_blueprint(dimensioning_blueprint)

应用的入口点是 main.py

import os

from app import create_app
from app.extensions import db
from app.pv_dimensioning.services.data import data
from config import config_by_name

config_name = os.getenv("FLASK_CONfig") or "default"
app_config = config_by_name[config_name]
app = create_app(app_config)

db.create_all(app=app)

with app.app_context():
    v = data(app)

print(v)

print(v)输出如下:

{'v': ('Solarmodul Canadian Solar HiKu CS3L-370MS 370Wp','Solarmodul Longi LR4-60HIH-370M,370Wp','Solarmodul Solar Fabrik mono S3 - Halfcut 360Wp','Solarmodul Energetica e.Classic M HC black - 360Wp','Solarmodul Yingli YL280P-29b-YGE 60 Cell Series 2 - poly,280Wp','Solarmodul Suntech Power STP370S-B60/Wnh,'Solarmodul AXITEC AXIworldpremium X HC AC-340MH/120S,340Wp','Solarmodul Longi LR4-72HIH-440M,440Wp','Solarmodul Seraphim SRP-330-BMB-DG 330Wp','Solarmodul Sharp NU-JD 440Wp')}

我希望在 v 参数的 controller.py 中使用这些 'vendor' 值。

我尝试通过在 v添加 main.py 来从 from main import v 获取 controller.py 的值,但它显示以下错误

ImportError: cannot import name 'v' from 'main'

我做错了什么?

感谢任何帮助。

谢谢

解决方法

我不是 flask_restx 方面的专家,但根据我的理解,choices 参数采用可迭代对象,因此您应该能够简单地传递 data 的返回值功能。

数据.py

from ..models.vendor_models import AdminVendor

def data():
    values = AdminVendor.query.all()
    v = [value.name for value in values]
    return {'v': tuple(v)}

控制器.py

from flask_restx import Resource,reqparse
from .services.data import data 

parser = reqparse.RequestParser()

parser.add_argument(
    "vendor",choices=data()['v'],help="Select the vendor")

关于导入错误,Mindslave 指出这很可能是循环导入错误,请参阅此 question 以了解更多详细信息。通常,这些可以通过将导入从模块顶部移到函数/类中来避免,例如:

from flask_restx import Resource,reqparse



def load_parser():
    from .services.data import data # avoid circular import

    parser = reqparse.RequestParser()
    parser.add_argument(
        "vendor",help="Select the vendor")
    return parser

parse = load_parser()

附带说明,请注意 reqparse 计划从flask_restx 中删除,因此在您深入了解它之前可能值得考虑一个不同的选项:

警告 Flask-RESTX 的整个请求解析器部分预定用于 删除并将被有关如何与 其他可以更好地处理输入/输出的包(例如 棉花糖)。这意味着它会一直维持到 2.0 但 认为它已弃用。别担心,如果你现在有使用它的代码 并希望继续这样做,它也不会消失 很快。

来源:https://flask-restx.readthedocs.io/en/latest/parsing.html