2016-05-12 42 views
0

我在检索数据库中的数据时遇到问题 我正在使用Mysql数据库和一个包含15个字段的表,我将在表中的模板上显示它。Django检索数据库中的数据到模板

它拥有超过400万条记录在表中,

def index(request): 
    args = {} 
    data = Mymodel.objects.all() 
    args['data'] = data 
    return render(request, 'index.html', args) 

我试过这种方式,但数据加载速度非常非常缓慢,

和明年的方法我试过数据库连接

def index(request): 
    args = {} 
    sql = "select * from mymodel" 
    cursor = connection.cursor() 
    cursor.execute(sql) 
    result = cursor.fetchall() 
    args['result'] = result 
    return render(request, 'index.html', args) 

这也是一样的,我需要更快地加载数据。请向我建议任何可以更快加载数据的方法。

+2

您试图展示400万条记录,它永远不会很快,您需要决定您实际需要*显示的内容 – Sayse

+0

请查看Django的分页API:https://docs.djangoproject。 com/en/1.9/topics/pagination/ – sam

+0

分页是加快速度的最佳途径。查询然后尝试显示400万条记录是不可取的。 – formatkaka

回答

1

解决方案之前的一个概念纠正是使用原始的sql并没有比django ORM做得更好,而且您也失去了使用ORM api轻松显示数据的能力。

常见的解决方案是使用分页构建的django来仅显示每页一定量的记录。 Django doc对分页的使用有非常详细的解释。

+0

“......使用原始的sql并没有比django ORM做得更好”ORM确实增加了一些开销(尤其是内存开销),这通常是可以接受的折衷,但在这些情况下可能会成为问题。 –

+3

@ fabio.sussetto - 你在说什么开销?它不在数据库端,因为它涉及到相同的查询,并且它不能用于检索结果,因为您需要以相同的方式执行该操作。所以如果你正在谈论创建sql查询,那么这就是废话,因为它不是密集的,并且对于'objects.all()'来说绝对不是密集的。我还没有找到一个原始查询的需要。 – Sayse

+1

必须创建所有模型实例对象确实有开销,而不是使用cursor.fetchall() –

1

由于您已经在执行一个原始查询,我认为您不会比现在做得更好。

你有什么理由不能对结果进行分页吗?通常你永远不会返回所有可用的数据。

您可以尝试使用QuerySet.iterator,以避免必须一次将所有实例加载到内存中。此外,QuerySet.values将返回字典而不是完整的模型实例,从而减少内存使用量。

如果您绝对需要并且遇到请求超时,则有一个选项是在后台运行实际的数据检索。例如,您可以使用Celery并将查询作为任务的一部分运行。您的视图会触发Celery任务并在响应中返回任务标识符。然后,消费者可以轮询一个“工作状态”端点传递此类任务ID,并在准备就绪时检索结果。您仍然需要将结果存储在其他地方(比您的数据库更快),即Redis(您可以轻松将其用作Celery后端)。

这种方法显然更加复杂,并且会为您的系统添加一些移动部件,无论如何您可能会遇到其他问题(例如响应大小)。如果可能的话使用分页会容易得多。

1

如果您希望系统为数千条记录工作,则可以使用分页。 Django genaric ListView将在这种情况下帮助你。它们很容易使用。他们是这样的

class YourView(ListView): 
    template_name = 'books/acme_list.html' 
    context_object_name = 'object_list' 
    queryset = TableName.objects.all() 
    paginate_by = 50 

你的模板将是这样

<table id="exam"> 
    {% for object in object_list %} 
    <tr> 
    <td>{{ object }}</td> 
    </tr> 
    {% endfor %} 
</table> 

而且你PAGINATE节会是这样

{% if is_paginated %} 
    <ul class="pagination"> 
    {% if page_obj.has_previous %} 
     <li> 
     <span><a href="?page={{ page_obj.previous_page_number }}">Previous</a></span> 
    </li> 
    {% endif %} 
     <li class=""> 
     <span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.</span> 
     </li> 
    {% if page_obj.has_next %} 
     <li> 
     <span><a href="?page={{ page_obj.next_page_number }}">Next</a></span> 
     </li> 
    {% endif %} 
     </ul> 
{% endif %} 

您可以在此link和Django的文档中找到更详细。