我目前让我的烧瓶静态运行,在那里我独立运行ETL作业,然后使用烧瓶中的结果数据集来显示chartjs折线图。
然而,我想在我的web框架中集成ETL部分,在那里我的用户可以登录并使用HTML表单提交输入参数(输入文件的位置和添加的版本id(,然后我的ETL作业将使用HTML表单运行并直接使用结果数据在同一页面上显示图表。
当前设置:
我的自定义ETL模块有几个子模块,它们一起作用形成一个简单的管道过程:
globals.py-有我的全局变量,比如s3的位置等等。理想情况下,我希望我的用户表单输入存储在这里,这样它们就可以在任何必要的地方直接用于我的所有子模块。
s3_bkt = 'abc' #change bucket here
s3_loc = 's3://'+s3_bkt+'/'
ip_loc = 'alv-input/'
#Ideally ,I'd like my users form inputs to be sitting here
# ip1 = 'alv_ip.csv'
# ip2 = 'Input_product_ICL_60K_Seg15.xlsx'
#version = 'v1'
op_loc = 'alv-output/'
---main-module.py-主要功能
import module3 as m3
import globals as g
def main(ip1,ip2,version):
data3,ip1,ip2,version = m3.module3(ip1,ip2,version)
----perform some actions on the data and return---
return res_data
---模块3.py
import module2 as m2
def mod3(ip1,ip2,version):
data2,ip1,ip2,version = m2.mod2(ip1,ip2,version)
----perform some actions on the data and return---
return data3
---模块2.py
import module1 as m1
import globals as g
def mod2(ip1,ip2,version):
data1,ip1,ip2,version = m1.mod1(ip1,ip2,version)
data_cnsts = pd.read_csv(ip2) #this is where i'll be using the user's input for ip2
----perform some actions on the datasets and write them to location with version_id to return---
data1.to_csv(g.op_loc+'data2-'+ version + '.csv', index=False)
return data2
---模块1.py
import globals as g
def mod1(ip1,ip2,version):
#this is the location where the form input for the data location should be actually used
data = pd.read_csv(g.s3_loc+g.ip_loc+ip1)
----perform some actions on the data and return---
return data1
烧瓶设置:
import main-module as mm
app = Flask(__name__)
#this is where the user first hits and submits the form
@app.route('/form')
def form():
return render_template('form.html')
@app.route('/result/',methods=['GET', 'POST'])
def upload():
msg=''
if request.method == 'GET':
return f"The URL /data is accessed directly. Try going to '/upload' to submit form"
if request.method == 'POST':
ip1 = request.form['ip_file']
ip2 = request.form['ip_sas_file']
version = request.form['version']
data = mm.main(ip1,ip2,version)
grpby_vars = ['a','b','c']
grouped_data = data.groupby(['mob'])[grpby_vars].mean().reset_index()
#labels for the chart
a = [val for val in grouped_data['a']]
#values for the chart
b = [round(val*100,3) for val in grouped_data['b']]
c = [round(val*100,3) for val in grouped_data['c']]
d = [val for val in grouped_data['d']]
return render_template('results.html', title='Predictions',a=a,b=b,c=c,d=d)
在不使用用户的任何形式输入的情况下(如果ETL作业和Flask不耦合,即当我运行ETL并直接向Flask提供结果数据位置时(,Flask设置工作得非常好
问题:
集成后的问题是,我不太确定如何将这些输入从用户传递到我的所有子模块。以下是使用当前设置时出现的错误。
data3,ip1,ip2,version = m3.module3(ip1,ip2,version)
TypeError: module3() missing 3 required positional arguments: 'ip1', 'ip2', and 'version'
所以,这肯定是由于我的参数在子模块之间传递的问题。
因此,我的问题是如何将表单中的数据用作子模块中的全局变量。理想情况下,我希望它们存储在我的全局变量中,这样我就不必将它们作为参数传递给所有模块。
有标准的方法来实现这一点吗?听起来可能很琐碎,但我正在努力达到我的最终状态。
感谢阅读:(
我意识到我的愚蠢错误,我本应该包括
data,ip1,ip2,version = mm.main(ip1,ip2,version)
我也可以使用我的全局文件,用空字符串启动输入,然后在flask文件中导入我的全局并更新值。这样我就可以避免通过我的子模块传递参数的路线。