2011-10-17 110 views
0

我需要在多个表上执行原始的sql。然后我渲染结果集。对于一个表,我会做:django/python:与多个表的原始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) 

可是,我真的需要创建一个表/模型/类big_model,它包含了所有领域,我可能需要?我永远不会在这个“表格”中存储任何数据。

添加:

我有一个表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表格只引用使用简单的数据模型。

+0

目前尚不清楚你在这里试图完成什么。也许显示关于你的模型的更多细节以及这个查询意味着做什么会有所帮助。 –

+0

我想从多个表中选择表中的外键连接。我不需要帮助编写实际的查询。对不起,我不确定为什么不明确:( – user984003

+0

它看起来像你需要帮助的查询。我不知道你为什么认为你需要原始SQL来做到这一点在Django。如果你不需要帮助编写查询,然后我对你提问的想法更少了 –

回答

1
  1. 这是有效的。不知道为什么它没有之前:(从丹尼斯·贝克的评论:

你不需要有在它的所有字段的模型,你只需要从第一模型和领域你。确实需要具有唯一名称的字段,并且据我所知,应该使用“tablename.field as fieldname”来确保您具有所有唯一字段。我已经以这种方式完成了一些相当复杂的查询将它们绑回到一个模型中 -

2.另一个解决方案是使用游标,但是游标必须从元组列表改为字典列表,我相信有更清晰的方法使用迭代器,但这个函数工作,它需要一个字符串,这是原始的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 
+0

使用游标时,如何将每一行映射到模型?我对Django完全陌生。 django服务器是否缓存模型实例,从本质上复制数据库中的数据?当您的API在生产中被击中时,数据是来自缓存的模型数据,还是每次都执行游标对象?谢谢! –

0

你不需要一个包含你想从原始sql返回的字段的模型。如果你碰巧有一个模型实际上有你想从原始sql返回的字段,那么你可以将你的原始sql输出映射到这个模型,否则你可以使用cursors来完成模型。

+0

这里的文档https://docs.djangoproject.com/en/dev/topics/db/sql/说“raw()会自动将查询中的字段映射到模型上的字段。”这表明我必须有一个至少包含查询字段的模型。由于查询从两个表中生成字段,那么我必须有第三个包含这些字段的模型,否?这是我希望避免的。 – user984003

+0

我花了一段时间才明白问题:)这是一个非常好的问题,我认为django在这个领域缺乏很多。我改变了我的答案。 – akonsu

+0

你不需要有一个模型,其中的所有领域,你只需要第一个模型和领域。你确实需要拥有唯一名称的字段,并且据我所知应该使用“tablename.field as fieldname”来确保你拥有所有独特的字段。我用这种方式做了一些相当复杂的查询,并且总是将它们绑定回单一模型。 –