【发布时间】:2015-08-28 11:24:40
【问题描述】:
突然间,我的页面在 db 中获得了如此多的用户,以至于 auth_user 表上的电子邮件过滤器几乎由于用户数量众多而失败。
由于表格是内置的,我需要将db_index=True 添加到此表格的列中,知道该怎么做吗?
【问题讨论】:
标签: django django-models django-authentication
突然间,我的页面在 db 中获得了如此多的用户,以至于 auth_user 表上的电子邮件过滤器几乎由于用户数量众多而失败。
由于表格是内置的,我需要将db_index=True 添加到此表格的列中,知道该怎么做吗?
【问题讨论】:
标签: django django-models django-authentication
一种可能性是将用户模型替换为自定义模型,该模型将具有适当的索引和您需要的任何其他字段。在Django docs: Substituting a custom User model 上有大量关于如何实现这一点的文档。这就是我在具有类似问题的特定案例中的做法。
另一种可能性是extend the user model,它可能有一个从原始模型重复的特定字段,在该字段上有一个索引。 免责声明:出于显而易见的原因,我真的反对这种做法,但我已经看到这种情况发生了,因为这种方法比第一种方法更容易编码。如果有很多字段,这将是非常糟糕的。
这是一个很好的问题。我很想知道是否还有其他我想念的可能性。
【讨论】:
一种快速简便的方法是在迁移中使用RunSQL 手动添加索引。
operations = [
migrations.RunSQL("CREATE INDEX..."),
]
它不是很优雅。一方面,迁移将针对不同的应用程序(因为您无法控制 auth 迁移)。另一方面,模式在技术上将与数据库不同步。但是,我认为在这种情况下不会有任何负面影响,因为 Django 除了创建索引之外,不会对 db_index 做任何事情。
【讨论】:
我遇到了同样的问题,但有一个额外的转折——我的表中已经有一个由 South 创建的索引。因此,如果我在迁移中添加了RunSQL("Create index"),它会在我的数据库中添加第二个索引。但与此同时,如果我不在迁移中包含一些创建索引操作,那么我将无法正确启动新数据库。
这是我的解决方案,一些 python 代码使用schema_editor 中的一些私有方法检查索引是否存在
project/appname/migrations/0002.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db.migrations import RunPython
def forward__auth_user__email__index(apps, schema_editor):
auth_user = apps.get_model("auth", "User")
target_column_to_index = 'email'
se = schema_editor
# if there aren't any indexes already, create one.
index_names = se._constraint_names(auth_user, [target_column_to_index], index=True)
if len(index_names) == 0:
se.execute(se._create_index_sql(auth_user, [auth_user._meta.get_field('email')]))
def reverse__auth_user__email__index(apps, schema_editor):
auth_user = apps.get_model("auth", "User")
target_column_to_index = 'email'
se = schema_editor
# delete any indexes for this table / column.
index_names = se._constraint_names(model, [target_column_to_index], index=True)
for index_name in index_names:
se.execute(se._delete_constraint_sql(se.sql_delete_index, auth_user, index_name))
class Migration(migrations.Migration):
dependencies = [
('frontend', '0001_initial'),
]
operations = [
RunPython(forward__auth_user__email__index, reverse_code=reverse__auth_user__email__index)
]
【讨论】: