Django模型:动态更改db_table

丹德夫

我有大量的数据集。每组数据包含几个数据库表。数据库表集的模式是相同的。每组表可以有超过一百万行。每组数据都属于一个作业,作业之间没有关系。一个或多个作业属于另一位用户。表集被导入,并最终作为表集删除。从性能的角度来看,最好将它们保留为单独的表集。

所以我想为几个表中的每一个创建几个通用的Django模型。通过使用类似于以下的代码,我已经在views.py文件中实现了它:

from foobar.models import Foo, Bar

def my_view(request):
  prefix = request.GET.get('prefix')
  Foo._meta.db_table = prefix + '_foo'
  Bar._meta.db_table = prefix + '_bar'
  ....

  foobar_list = Foo.objects.filter(bar_id=myval)
  ...

我的问题是:与基于Django的Web应用程序的并发多个用户一起使用此代码是否安全?模型对象是否在用户之间共享?如果同时有两个请求怎么办?

编辑2:我考虑了李·赖安(Lie Ryan)的回答和评论,并提出了以下代码:

from django.http import HttpResponse, HttpResponseNotFound
from django.db import models
from django.template import RequestContext, loader

def getModels(prefix):
    table_map = {}

    table_map["foo"] = type(str(prefix + '_foo'), (models.Model,), {
        '__module__': 'foobar.models',
        'id' : models.IntegerField(primary_key=True),
        'foo' : models.TextField(blank=True),
        })
    table_map["foo"]._meta.db_table = prefix + '_foo'

    table_map["bar"] = type(str(prefix + '_bar'), (models.Model,), {
        '__module__': 'foobar.models',
        'id' : models.IntegerField(primary_key=True), 
        'foo' : models.ForeignKey(prefix + '_foo', null=True, blank=True),
        })
    table_map["bar"]._meta.db_table = prefix + '_bar'

    return table_map

def foobar_view(request):  
    prefix = request.GET.get('prefix')
    if prefix != None and prefix.isdigit():
        table_map = getModels(prefix)
        foobar_list = table_map["bar"].objects.filter.order_by('foo__foo')
        template = loader.get_template('foobar/foobar.html')
        context = RequestContext(request, {
            'foobar_list': foobar_list,
        })
        return HttpResponse(template.render(context))
    else:
        return HttpResponseNotFound('<h1>Page not found</h1>')

现在我的问题是,经过编辑的代码的第二稿对并发多个用户是否安全?

烈瑞恩

这种技术称为分片。不,如果您通过线程处理并发请求,这样做是不安全的。

您可以做的是动态构造指向不同db_tables的多个类,并使用工厂选择正确的类。

tables = ["foo", "bar"]
table_map = {}
for tbl in tables:
    class T(models.Model):
        db_table = tbl
        ... table definition ...
    table_map[tbl] = T

然后创建一个函数,该函数根据您的数据分片方式选择正确的table_map。

如果您接受来自用户输入的表名,也要小心注入。

或者,某些数据库系统(如PostgrSQL)允许每个数据库多个模式,这在某些情况下可能是分离数据的更好方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章