"Row is not JSON serializable" 将结果集发送到 Flask 视图时出错

"Row is not JSON serializable" error when sending result set to a Flask view

我正在尝试将 pyodbc 查询的结果发送到我的视图,但我收到 TypeError: Object of type Row is not JSON serializable.

假设我在 SQL 服务器中有一个这样的 table:

col1 col2 col3
1 val1 val2
2 val3 val4

我正在通过 pyodbc 查询它并将数据传递给视图,如下所示:

return render_template(
    'index.html'
    ,data={
        'foor':'bar'
        ,'rows':db.execute(
            'SELECT * '
            'FROM [' + table.schema_name + '].[' + table.table_name + ']'
        ).fetchall()
    }
)

如果我打印 {{ data.rows }} 我想要 [[1,"val1","val2"],[2,"val3","val4"]] 但我得到 [(Decimal('1'), 'val1', 'val2'), (Decimal('2'), 'val3', 'val4')].

如果我在控制器中 print(type(data.rows)) 我得到 <class 'list'>.

尝试在视图中将其转换为 JSON,结果是 {{ data.rows|tojson }} TypeError: Object of type Row is not JSON serializable。如何实现我的需求?

fetchall() returns pyodbc.Row 个对象的列表。行对象类似于元组,但正如错误消息所述,它们不是 JSON 可序列化的。

results = crsr.execute(query).fetchall()
print(f"{type(results)} of type {type(results[0])}")
# <class 'list'> of type <class 'pyodbc.Row'>

json_string = json.dumps(results)
# TypeError: Object of type Row is not JSON serializable

我们可以将 Row 对象转换为真正的元组,以便它们可以序列化:

results = [tuple(row) for row in results]
print(f"{type(results)} of type {type(results[0])}")
# <class 'list'> of type <class 'tuple'>

json_string = json.dumps(results)
# no error (unless the tuples themselves contain elements that are not serializable)

如果元组确实包含不可序列化的元素(如 Decimal 对象),那么我们可以将它们强制转换为字符串……

json_string = json.dumps(results, default=str)

... 或者我们可以修改查询以将小数转换为浮点数,例如,使用

query = "SELECT CAST(x AS FLOAT) AS x FROM tbl"

而不是

query = "SELECT x FROM tbl"