在 Django API 中从 PostgreSQL Procedure/Function 获取错误输出
Getting wrong Output from PostgreSQL Procedure/Function in Django API
我已经在 PostgreSQL 中准备好我的数据库及其所有过程。我以前使用 Laravel 作为我的 API 的后端,所有程序都正常工作并返回正确的输出。
我的 Laravel 控制器函数 API 调用之一如下:
public function retrieve() {
$data = DB::select(DB::raw("SELECT * FROM showallmenuitem()"));
$status = count($data);
return $status ? response(['message'=>'Menu item retrieved successfully','data' =>$data],200):response(['message'=>'Failed to retrieve menu item.']);
}
此方法调用showallmenuitem()
过程,存储在$data
变量中的输出如下:
{
"message": "Menu item retrieved successfully",
"data": [
{
"meniuid": 1,
"menuitemsname": "User"
},
{
"meniuid": 2,
"menuitemsname": "Payment"
}
]
}
但最近我将后端从 Laravel 更改为 Django,因为我的应用程序中需要一些 AI 功能,而我需要的 AI 模型是用 python 编写的。所以我创建了一个简单的视图来从 Django 调用相同的过程。我期待与 Laravel 相同的输出,但 Django 以错误的格式给我输出。我正在使用 psycopg2 作为数据库驱动程序。
这是我的 Django 视图代码:
@csrf_exempt
def retrieve(request):
if request.method == 'GET':
with connection.cursor() as cursor:
cursor.callproc("showallmenuitem")
results = cursor.fetchall()
response = {
'message' : 'Menu items retrieved successfully',
'data' : results
}
return JsonResponse(response, safe=False, status= 200)
我得到以下格式的输出:
{
"message": "Menu items retrieved successfully",
"data": [
[
1,
"User"
],
[
2,
"Payment"
],
]
}
Note:
I have also tried running execute
function instead of callproc
as written below and still get the same output.
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM showallmenuitem()")
results = cursor.fetchall()
所以我的问题是如何在 Django 中以正确的 json 格式获得输出,就像我从 Laravel?
得到的一样
默认情况下 psycopg2
returns 一个元组列表,您会看到它被转换为 JSON
作为数组的数组。要更改此设置,请参见此处:
https://docs.djangoproject.com/en/3.0/topics/db/sql/
Executing custom SQL directly
By default, the Python DB API will return results without their field names, which means you end up with a list of values, rather than a dict. At a small performance and memory cost, you can return results as a dict by using something like this:
def dictfetchall(cursor):
"Return all rows from a cursor as a dict"
columns = [col[0] for col in cursor.description]
return [
dict(zip(columns, row))
for row in cursor.fetchall()
]
我已经在 PostgreSQL 中准备好我的数据库及其所有过程。我以前使用 Laravel 作为我的 API 的后端,所有程序都正常工作并返回正确的输出。
我的 Laravel 控制器函数 API 调用之一如下:
public function retrieve() {
$data = DB::select(DB::raw("SELECT * FROM showallmenuitem()"));
$status = count($data);
return $status ? response(['message'=>'Menu item retrieved successfully','data' =>$data],200):response(['message'=>'Failed to retrieve menu item.']);
}
此方法调用showallmenuitem()
过程,存储在$data
变量中的输出如下:
{
"message": "Menu item retrieved successfully",
"data": [
{
"meniuid": 1,
"menuitemsname": "User"
},
{
"meniuid": 2,
"menuitemsname": "Payment"
}
]
}
但最近我将后端从 Laravel 更改为 Django,因为我的应用程序中需要一些 AI 功能,而我需要的 AI 模型是用 python 编写的。所以我创建了一个简单的视图来从 Django 调用相同的过程。我期待与 Laravel 相同的输出,但 Django 以错误的格式给我输出。我正在使用 psycopg2 作为数据库驱动程序。 这是我的 Django 视图代码:
@csrf_exempt
def retrieve(request):
if request.method == 'GET':
with connection.cursor() as cursor:
cursor.callproc("showallmenuitem")
results = cursor.fetchall()
response = {
'message' : 'Menu items retrieved successfully',
'data' : results
}
return JsonResponse(response, safe=False, status= 200)
我得到以下格式的输出:
{
"message": "Menu items retrieved successfully",
"data": [
[
1,
"User"
],
[
2,
"Payment"
],
]
}
Note:
I have also tried runningexecute
function instead ofcallproc
as written below and still get the same output.
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM showallmenuitem()")
results = cursor.fetchall()
所以我的问题是如何在 Django 中以正确的 json 格式获得输出,就像我从 Laravel?
得到的一样默认情况下 psycopg2
returns 一个元组列表,您会看到它被转换为 JSON
作为数组的数组。要更改此设置,请参见此处:
https://docs.djangoproject.com/en/3.0/topics/db/sql/
Executing custom SQL directly
By default, the Python DB API will return results without their field names, which means you end up with a list of values, rather than a dict. At a small performance and memory cost, you can return results as a dict by using something like this:
def dictfetchall(cursor):
"Return all rows from a cursor as a dict"
columns = [col[0] for col in cursor.description]
return [
dict(zip(columns, row))
for row in cursor.fetchall()
]