我很好奇如何在django中创建一个临时表?(数据库为mysql,客户端要求)
CREATE TEMPORARY TABLE somewhat_like_a_cache AS
(SELECT * FROM expensive_query_with_multiple_joins);
SELECT * FROM somewhat_like_a_cache LIMIT 1000 OFFSET X;
这背后的原因是:结果集相当大,我必须迭代它。代价高昂的查询大约需要30秒。在没有临时表的情况下,我给数据库服务器增加了几个小时的压力。使用临时表,开销很大的查询只执行一次,之后在分片迭代临时表的成本很低。
这不是How do I create a temporary table to sort the same column by two criteria using Django's ORM?的副本。作者只想按两列排序。
发布于 2013-11-28 10:07:46
我已经解决了这个问题,并且我构建了一个函数来将模型同步到数据库(改编自管理脚本syncdb
。
您可以在代码中的任何位置编写临时模型,甚至可以在运行时生成模型,然后调用sync_models
。尽情享受ORM
顺便说一句,它的数据库是独立的,可以与任何支持django
的数据库后端一起使用
from django.db import connection
from django.test import TestCase
from django.core.management.color import no_style
from importlib import import_module
def sync_models(model_list):
'''
Create the database tables for given models.
'''
tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)
created_models = set()
pending_references = {}
cursor = connection.cursor()
for model in model_list:
# Create the model's database table, if it doesn't already exist.
sql, references = connection.creation.sql_create_model(model, no_style(), seen_models)
seen_models.add(model)
created_models.add(model)
for refto, refs in references.items():
pending_references.setdefault(refto, []).extend(refs)
if refto in seen_models:
sql.extend(connection.creation.sql_for_pending_references(refto, no_style(), pending_references))
sql.extend(connection.creation.sql_for_pending_references(model, no_style(), pending_references))
for statement in sql:
cursor.execute(statement)
tables.append(connection.introspection.table_name_converter(model._meta.db_table))
发布于 2013-11-25 12:58:22
我在Postgresql中测试了以下内容(也很少使用),但我认为您不会有任何问题。
Django还提供了一个使用connection
执行自定义SQL查询(INSERT, UPDATE, CREATE, DROP
等)的应用编程接口。关于用法的Here is the documentation
from django.db import connection, transaction
cursor = connection.cursor() # create the cursor
cursor.execute("CREATE TEMPORARY TABLE test_table (code char(5) PRIMARY KEY,
title varchar(40) NOT NULL);")
cursor.execute("INSERT into test_table (code, title) values ('ABVCD', 'This is my Title');")
cursor.execute("select * from test_table;") # now select all data in our table
print cursor.fetchall() # and fetch them all
cursor.close() # if you wish to close it
这是我用jPostgreSQL9.1测试的示例代码,但是如果执行适合您的DBMS版本的查询,就不会有任何问题。
使用TEMPORARY
表或创建普通表并在完成工作后执行drop语句由您决定。但在开始之前先阅读文档。
https://stackoverflow.com/questions/20138428
复制相似问题