将结果集发送到 Flask 视图时出现“行不是 JSON 可序列化”错误

7 sql-server json pyodbc flask

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

假设我在 SQL Server 中有一个这样的表:

第 1 列 列2 第 3 列
1 值1 值2
2 值3 值4

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

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

如果我打印{{ 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. 如何实现我的需求?

Gor*_*son 9

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

\n
results = crsr.execute(query).fetchall()\nprint(f"{type(results)} of type {type(results[0])}")\n# <class \'list\'> of type <class \'pyodbc.Row\'>\n\njson_string = json.dumps(results)\n# TypeError: Object of type Row is not JSON serializable\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
results = [tuple(row) for row in results]\nprint(f"{type(results)} of type {type(results[0])}")\n# <class \'list\'> of type <class \'tuple\'>\n\njson_string = json.dumps(results)\n# no error (unless the tuples themselves contain elements that are not serializable)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
json_string = json.dumps(results, default=str)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
query = "SELECT CAST(x AS FLOAT) AS x FROM tbl"\n
Run Code Online (Sandbox Code Playgroud)\n

代替

\n
query = "SELECT x FROM tbl"\n
Run Code Online (Sandbox Code Playgroud)\n