通过函数添加db.model对象会导致< unprintable interfaceerror object>

ar5n3qh5  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(447)

在我的flask web应用程序中,用户可以上传必须使用适当模型提交到数据库的数据。我创建了一个函数,它接收用户的数据并返回要添加到数据库中的适当填充对象。我的问题是,当我尝试使用一个函数来创建并返回这个对象时,我在尝试将它提交到数据库时遇到了错误。
我已经测试了它和以下作品;

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:error-binding-parameter 0-可能是不支持的类型”错误,但从错误堆栈中看不清楚它具体指的是什么。这种方法是不可行的吗?

ckocjqey

ckocjqey1#

我发现我忽略了构建类的一个关键方面,但后来发现实际问题与此无关。
定义 __init__(self, x, y,z): 每个类的一部分允许比我在这里展示的更灵活的赋值。这意味着我可以将一系列值传递回主视图,将它们分配给对象,并将该对象添加到主视图中的db会话中。如果对数据库使用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')

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

相关问题