: wtforms.form 上的属性查找元失败,python,multithreading,flask,flask-sqlalchemy"/>

首页 > 解决方案 > Python:_pickle.PicklingError:不能腌制: wtforms.form 上的属性查找元失败

问题描述

背景:

我构建了一个应用程序,当用户浏览文件并单击“上传”按钮时,会进行幕后计算,这可能需要很长时间,最后将输出上传到 GCP . 我希望计算(点击后)不会卡住应用程序,同时用户将被移动到另一个页面。在该过程结束时,他将收到一封成功/失败电子邮件。为了实现这个目标,我尝试使用multiprocessing. 我在尝试将其转换为多处理应用程序时遇到了很多麻烦 - 当我尝试启动进程时,我不断收到以下错误消息:

_pickle.PicklingError: Can't pickle <class 'wtforms.form.Meta'>: attribute lookup Meta on wtforms.form failed

app.py - 主要功能是`upload_file:

@app.route('/')
def home():
    return redirect(url_for('upload_file', page_num=1))


@app.route('/<int:page_num>', methods=['GET', 'POST'])
def upload_file(page_num=1):
    form = CreateXslxForm()
    traffic_data = get_page_of_traffic_data(page_num)
    queue = Queue()
    p = Process(target=main_func, args=(queue, form))
    p.start()
    proc_ret = queue.get()
    if proc_ret:
        upload_success(*proc_ret)
    else:
        return render_template(constants.GeneralConstants.LANDING_PAGE, title='URL Comparison', form=form,
                               traffic_data=traffic_data)


def get_page_of_traffic_data(page_num):
    traffic_data = urls_comparison_users_traffic.query.paginate(per_page=5, page=int(page_num), error_out=True)
    return traffic_data


def upload_success(link, traffic_row, blob_name):
    add_data_to_db(traffic_row)
    return render_template('upload_success.html', title='Upload File', file_path=link, filename=blob_name)


def add_data_to_db(traffic_row):
    # MANUAL PRE PING
    try:
        db.session.execute("SELECT 1;")
        db.session.commit()
    except:
        db.session.rollback()
    finally:
        db.session.close()
    # SESSION COMMIT, ROLLBACK, CLOSE
    try:
        db.session.add(traffic_row)
        db.session.commit()
        send_response_mail_to_user(traffic_row)
    except Exception as e:
        db.session.rollback()
        raise e
    finally:
        db.session.close()


def send_response_mail_to_user(traffic_data):
    sendgrid_obj = sendgrid_handler.SendgridHandler(sendgrid_key=SENDGRID_KEY)
    sendgrid_obj.mails_to_send = URLComparisonEmailBuilder.build_mails(traffic_data)
    sendgrid_obj.send()


if __name__ == "__main__":
    app.run(port=5000, debug=True, threaded=True)

主文件

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = r'gcp-cre.json'

storage_client = storage.Client()

def get_file_from_form(form):
    # form = forms.CreateXslxForm()
    timestr = time.strftime(constants.DatesFormats.DATETIME)
    custom_name = f"{constants.GeneralConstants.DEST_DEFAULT_NAME}-{timestr}"

    # traffic_data = get_page_of_traffic_data(page_num)

    if form.validate_on_submit():
        load_filename = secure_filename(form.input_file.data.filename)
        valid_file_name = get_valid_filename(request.form["filename"])
        if valid_file_name:
            custom_name = f"{valid_file_name}"
        url_comp_obj = URLCompare()
        result = url_comp_obj.compare_all_urls(form.input_file.data)
        row_data = {
            "upload_file": form.input_file.data.filename,
            "output_file": custom_name,
            "gcp_link": None,
            "user": 'nki-tov'
        }
        return custom_name, result, constants.GeneralConstants.BUCKET_NAME, row_data



def get_valid_filename(s):
    s = s.strip().replace(' ', '_')
    return re.sub(r'(?u)[^-\w]', '', s)


def upload_to_bucket(blob_name, file, bucket_name, row_data):
    '''
    Upload file to a bucket
    : blob_name  (str) - object name
    : file_path (str)
    : bucket_name (str)
    '''
    bucket = storage_client.get_bucket(bucket_name)
    blob = bucket.blob(blob_name)
    blob.upload_from_file(file)
    link = f'https://console.cloud.google.com/storage/browser/_details/{bucket_name}/{blob_name};tab=live_object?authuser=0'

    row_data["gcp_link"] = link
    traffic_row = urls_comparison_users_traffic(**row_data)
    return link, traffic_row, blob_name


def main_func(queue: Queue, form):
    res = get_file_from_form(form)
    if res:
        queue.put(upload_to_bucket(*res))
    else:
        queue.put(res) # None

我究竟做错了什么?它与架构有关吗?

标签: pythonmultithreadingflaskflask-sqlalchemy

解决方案


推荐阅读