django/python:多表的原始SQL
我需要在多个表上执行原始 SQL 查询,然后把结果显示出来。对于一个表,我会这样做:
sql = "select * from my_table"
results = my_table.objects.raw(sql)
对于多个表,我是这样做的:
sql = "select * from my_table, my_other_table where ...."
results = big_model.objects.raw(sql)
但是,我真的需要创建一个包含所有可能需要字段的大模型吗?我实际上并不会在这个“表”中存储任何数据。
补充说明:
我有一个表叫 my_users,还有一个表叫 my_listings。这些表在 Models.py 中定义。my_listings 表有一个外键指向 my_users,表示是谁创建了这个列表。
SQL 查询是:
"select user_name, listing_text from my_listings, my_users where my_users.id = my_listings.my_user_id".
我希望这个 SQL 查询能生成一个结果集,以便我可以在 Django 中渲染我的页面。
我的问题是:我必须创建一个包含 user_name 和 listing_text 字段的模型吗?还是有更好的方法可以继续使用原始 SQL(select, from, where)?当然,我实际的查询比这个例子要复杂得多。(我在 models.py 中定义的模型会变成数据库中的实际表,所以我才用模型/表这个说法。不知道还有什么其他的说法,抱歉。)我使用原始 SQL 是因为我发现 Python 的表引用只适用于简单的数据模型。
2 个回答
你并不需要一个包含你想从原始SQL中返回的字段的模型。如果恰好你有一个模型,里面有你想要的字段,那么你可以把原始SQL的输出映射到这个模型上。否则,你可以使用游标,完全不使用模型。
- 这个方法有效。不知道之前为什么不行 :( 根据Dennis Baker的评论:
你并不需要一个包含所有字段的模型,只需要第一个模型和它的字段就可以了。你需要确保字段的名称是唯一的,尽量使用“tablename.field as fieldname”这种写法来确保字段名不重复。我用这种方法做过一些比较复杂的查询,涉及5个以上的表,结果总是能和一个单一的模型关联起来。
另外一个解决方案是使用游标。不过,游标需要从元组列表转换成字典列表。我相信使用迭代器会有更简洁的方法,但这个函数是可以工作的。它接收一个字符串,也就是原始的SQL查询,然后返回一个可以在模板中渲染和使用的列表。
from django.db import connection, transaction
def sql_select(sql):
cursor = connection.cursor()
cursor.execute(sql)
results = cursor.fetchall()
list = []
i = 0
for row in results:
dict = {}
field = 0
while True:
try:
dict[cursor.description[field][0]] = str(results[i][field])
field = field +1
except IndexError as e:
break
i = i + 1
list.append(dict)
return list