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

2024-10-01 17:34:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用flask-restx为Flask应用程序提供了以下项目结构

.
├── 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,将其分配给一个变量,并将其作为add_argument()中的choices参数传递

我的代码:

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

我在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)

应用程序的入口点是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, 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')}

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

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

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

我犯了什么错误


Tags: namefrompyimportconfigappdbdata
1条回答
网友
1楼 · 发布于 2024-10-01 17:34:37

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

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)}

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")

关于导入错误,正如Mindsave指出的,这很可能是一个循环导入错误,请参阅此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",
        choices=data()['v'],  
        help="Select the vendor")
    return parser

parse = load_parser()

作为旁注,请注意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). This means that it will be maintained until 2.0 but consider it deprecated. 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.

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

相关问题 更多 >

    热门问题