,python,flask,flask-sqlalchemy"/>

首页 > 解决方案 > 通过函数添加 db.Model 对象导致

问题描述

在我的烧瓶网络应用程序中,用户可以上传必须使用适当模型提交到数据库的数据。我创建了一个函数,该函数接收用户数据并返回要添加到数据库中的适当填充对象。我的问题是,当我尝试使用函数创建并返回此对象时,尝试将其提交到数据库时出现错误。

我已经对其进行了测试,并进行了以下工作;

        if form.data_import.data == 'use_template':
            template = equip_model.ReportTemplate.query.filter_by(equip_id=equipment.id).first_or_404()
            keylist = pd.read_csv(os.path.join(current_app.config['UPLOAD_FOLDER'], template.keylist))
            wb = load_workbook(file)
            #function takes inputs and commits relevant information to correct model
            #output_metric = metric_decider(equipment, keylist, wb, datetime_combo, report)
            
            columns = equip_model.CTMetrics.__table__.columns.keys()
            i=4
            output_metric = equip_model.CTMetrics(
                equip_id = equipment.id,
                report_id = report.id,
                addendum_id = None,
                date_of_test = datetime_combo,
                ctdi_air_body = keylist_value(columns[i+1], keylist, wb),
                ctdi_air_head = keylist_value(columns[i+2], keylist, wb),
                ctdi_w_body = keylist_value(columns[i+3], keylist, wb),
                ctdi_w_head = keylist_value(columns[i+4], keylist, wb),
                mtf_a = keylist_value(columns[i+5], keylist, wb),
                mtf_b = keylist_value(columns[i+6], keylist, wb),
                cnr = keylist_value(columns[i+7], keylist, wb)
                )
            db.session.add(output_metric)
            db.session.commit()

而以下没有:

if form.data_import.data == 'use_template':
    template = equip_model.ReportTemplate.query.filter_by(equip_id=equipment.id).first_or_404()
    keylist = pd.read_csv(os.path.join(current_app.config['UPLOAD_FOLDER'], template.keylist))
    wb = load_workbook(file)
    #function takes inputs and commits relevant information to correct model
    output_metric = metric_decider(equipment, keylist, wb, datetime_combo, report)
    db.session.add(output_metric)
    db.session.commit()

该函数的代码片段是:

def ct_metric_object(equipment_id, keylist, wb, date_of_test, report_id=None, addendum_id=None):
    from app.equipment.models import CTMetrics
    columns = CTMetrics.__table__.columns.keys()
    i = 4 #number of columns not related to metrics
    ct_output = CTMetrics(
        equip_id = equipment_id,
        report_id = report_id,
        addendum_id = addendum_id,
        date_of_test = date_of_test,
        ctdi_air_body = keylist_value(columns[i+1], keylist, wb),
        ctdi_air_head = keylist_value(columns[i+2], keylist, wb),
        ctdi_w_body = keylist_value(columns[i+3], keylist, wb),
        ctdi_w_head = keylist_value(columns[i+4], keylist, wb),
        mtf_a = keylist_value(columns[i+5], keylist, wb),
        mtf_b = keylist_value(columns[i+6], keylist, wb),
        cnr = keylist_value(columns[i+7], keylist, wb)
    )
    return ct_output

上面的对象是从另一个函数中提取的:

def metric_decider(equipment, keylist, workbook, date_of_test, report = None, addendum = None):
    """
    Takes input Equipment and Report objects to discern the correct Metric model
    to commit data to DB with. Requires keylist and workbook in question as they
    will be passed to committing function.
    """
    category = equipment.category
    print(category)

    metric_commit_map = {
        'General Xray': gen_metric_object,
        'Fluoroscopy': fluoro_metric_object,
        'Mammography': mammo_metric_object,
        'Computed Tomography': ct_metric_object,
        'Nuclear Medicine': placeholder_function,
        'Magnetic Resonance Imaging': placeholder_function,
        'Ultraviolet': placeholder_function,
        'Lasers': placeholder_function
    }
    metric_func = metric_commit_map[category]
    print(metric_func)
    if report is not None:
        output_metric = metric_func(equipment, keylist, workbook, date_of_test, report.id)
        print('Report is not none')
    elif addendum is not None:
        output_metric = metric_func(equipment, keylist, workbook, date_of_test, addendum.id)
        print('Addendum is not none')
    else:
        print('Data added with no accompanying report or addenda.')
        output_metric = metric_func(equipment, keylist, workbook, date_of_test)
    return output_metric

我希望能够通过函数调用它的原因是会有多个视图会使用它,因此必须为每个实例批量编写它会使任何更新变得更加困难。

任何帮助将不胜感激 - 我只能辨别出有关从函数返回的对象的某些内容会破坏它,但我看不到是什么。在返回之前和之后打印对象显示它们是相同的。

我还看到“sqlite3.InterfaceError:错误绑定参数 0 - 可能不受支持的类型”错误,但从错误堆栈中不清楚它具体指的是什么。这种方法是不行的吗?

标签: pythonflaskflask-sqlalchemy

解决方案


发现我忽略了构建类的一个关键方面,但后来发现实际问题与它无关。

定义__init__(self, x, y,z):每个类的部分允许比我在这里显示的更灵活的值分配。这意味着我可以将值列表传递回主视图,将它们分配给对象并将该对象添加到主视图中的数据库会话中。如果您将 SQLite 用于数据库,这具有避免并发请求的额外好处。

不幸的是,虽然这很有帮助,但事实证明我的错误是一个完整的对象而不是所述对象的 ID 被传递到最后的参数中,我没有注意到它,因为它没有以我习惯的方式标记在调试窗口中。

if report is not None:
        output_metric = metric_func(equipment, keylist, workbook, date_of_test, report.id)
        print('Report is not none')

本来应该:

if report is not None:
        output_metric = metric_func(equipment.id, keylist, workbook, date_of_test, report.id)
        print('Report is not none')

一个愚蠢的错误,但它最终帮助我顺利完成了我的项目。


推荐阅读