简体   繁体   English

当 flask 应用程序启动时,如何使用从 DB 获得的数据作为 add_argument() 中的值?

[英]How to use data obtained from DB as values in add_argument() when the flask app starts?

I have the following project structure for a flask app using flask-restx我使用flask-restxflask应用程序具有以下项目结构

.
├── 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

In controller.py , I am adding the add_argument() statements and parsing them in the api routes.controller.py中,我添加了add_argument()语句并在 api 路由中解析它们。 In one of the add_argument() statement, I would like to add choices for the user.在其中一个add_argument()语句中,我想为用户添加choices For getting the choices, I am querying from the database and getting a list of values available.为了获得选择,我从数据库中查询并获取可用值list I then convert this list to a tuple , assign it to a variable, and pass it as choices parameter in the add_argument()然后我将此list转换为tuple ,将其分配给变量,并将其作为choices参数传递给add_argument()

My codes:我的代码:

data.py数据.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 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

where ns is the namespace .其中nsnamespace

My __init__.py file in the app folder is as follows:我的app文件夹中的__init__.py文件如下:

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)

and the entry point to the app is main.py应用程序的入口点是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)

The output of print(v) is as follows: print(v)的output如下:

{'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, 370Wp', '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')}

I want these values of v to be used in controller.py in the 'vendor' argument.我希望在'vendor'参数的controller.py中使用这些v值。

I have tried getting the values of v from main.py by adding from main import v in the controller.py , but it shows the following error我尝试通过在 controller.py 中添加from main import v v main.py获取 v 的controller.py ,但它显示以下错误

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

What is the mistake that I am doing?我在做什么错误?

Any help is appreciated.任何帮助表示赞赏。

Thanks谢谢

I'm not an expert on flask_restx , but from my understanding, the choices argument takes an iterable so you should simply be able to pass in the return value of your data function.我不是flask_restx方面的专家,但据我了解, choices参数采用可迭代的,因此您应该能够简单地传递data function 的返回值。

data.py数据.py

from ..models.vendor_models import AdminVendor

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

controller.py controller.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")

Regarding the import error, as Mindslave points out that is most likely a circular import error see this question for a bit more detail.关于导入错误,正如 Mindslave 指出的那样,这很可能是循环导入错误,请参阅此问题以获取更多详细信息。 Generally these can be avoided by moving the import from the top of the module to within a function/class, eg:通常,这些可以通过将导入从模块顶部移动到函数/类中来避免,例如:

from flask_restx import Resource, reqparse



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

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

parse = load_parser()

As a side note, be aware that reqparse is scheduled to be removed from flask_restx, so might be worth considering a different option before you get too embedded with it:作为旁注,请注意reqparse计划从 flask_restx 中删除,因此在您过度嵌入它之前可能值得考虑一个不同的选项:

Warning The whole request parser part of Flask-RESTX is slated for removal and will be replaced by documentation on how to integrate with other packages that do the input/output stuff better (such as marshmallow).警告 Flask-RESTX 的整个请求解析器部分将被删除,并将被有关如何与其他可以更好地执行输入/输出内容的包(例如棉花糖)集成的文档所取代。 This means that it will be maintained until 2.0 but consider it deprecated.这意味着它将保持到 2.0,但认为它已被弃用。 Don't worry, if you have code using that now and wish to continue doing so, it's not going to go away any time too soon.别担心,如果您现在有代码使用它并希望继续这样做,它不会很快消失 go。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM