python - Flask 应用程序启动时,如何使用从 DB 获取的数据作为 add_argument() 中的值?
问题描述
我使用以下 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
为 a tuple
,将其分配给一个变量,并将其作为choices
参数传递给add_argument()
我的代码:
数据.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)}
控制器.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
ns
在哪里namespace
。
我__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, 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')}
我希望在参数v
中使用这些值。controller.py
'vendor'
我尝试通过添加来获取v
from的值,但它显示以下错误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 指出的那样,这很可能是循环导入错误,请参阅此问题以获取更多详细信息。通常,这些可以通过将导入从模块顶部移动到函数/类中来避免,例如:
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中删除,因此可能值得考虑一个不同的选项,然后再过度嵌入它:
警告 Flask-RESTX 的整个请求解析器部分将被删除,并将被有关如何与其他可以更好地执行输入/输出内容的包(例如棉花糖)集成的文档所取代。这意味着它将保持到 2.0,但认为它已被弃用。不用担心,如果您现在有代码使用它并希望继续这样做,它不会很快消失。
来源:https ://flask-restx.readthedocs.io/en/latest/parsing.html
推荐阅读
- javascript - 如何在 devtools 网络上隐藏 mp4 视频?
- node.js - 使用 excel4node 在文件上写入大数据并使用大量时间下载并阻止所有其他 I/O 操作
- vba - 如何绕过空白/空 MailItem.To 属性的测试?
- ruby-on-rails - 如何使用 Ruby Tap 方法预填充种子数据
- sql - 使用 CHARINDEX 和 LEN 在 SUBSTRING 之后将 NVARCHAR 转换为 INT
- react-native - 使用 react-native-google-signin 无限期加载 youtube 的范围
- javascript - 使用选择器访问动态创建的元素
- angular - 在Angular中进行路由时如何将数据从组件传递到组件
- java - Hibernate 将子实体中的 ManyToOne 映射到父实体的复合键中的字段
- reactjs - TSX 脚本的意外令牌