Как добавить db_index=True в поле электронной почты django auth_user
Неожиданно моя страница получила столько пользователей в БД, что фильтр для электронной почты через auth_user
стол почти не работает из-за чрезвычайно большого количества пользователей.
Поскольку таблица поставляется встроенной, мне нужно добавить db_index=True
для столбцов в этой таблице, есть идеи, как это сделать?
3 ответа
Одним из быстрых и простых способов было бы вручную добавить индекс, используя RunSQL
в миграции.
operations = [
migrations.RunSQL("CREATE INDEX..."),
]
Это не очень элегантно. С одной стороны, миграция будет для другого приложения (так как вы не контролируете auth
Миграции). С другой стороны, схема будет технически не синхронизирована с базой данных. Тем не менее, я не думаю, что в этом случае есть какие-либо негативные последствия, так как Джанго ничего не делает с db_index
кроме создания индекса.
Одна из возможностей - заменить пользовательскую модель пользовательской моделью, которая будет иметь соответствующие индексы и любое другое поле, которое вам требуется. Существует обширная документация по Django docs: замена пользовательской модели на то, как этого добиться. Вот как я это сделал в конкретном случае с похожей проблемой.
Другая возможность состоит в расширении пользовательской модели, которая может иметь определенное поле, повторяемое из исходной модели, для которой существует индекс. Отказ от ответственности: я искренне против этого по очевидным причинам, но я видел, как это происходит, так как этот подход легче кодировать, чем первый. Это было бы очень плохо, если бы было много полей.
Это хороший вопрос IMO. Я хотел бы знать, есть ли другая возможность, которую я упускаю.
У меня была та же проблема, но с дополнительным поворотом - у меня уже был индекс, созданный Югом в моей таблице. Так что, если я добавил RunSQL("Create index")
к моей миграции, это добавило бы второй индекс в мою базу данных. Но в то же время, если я не включу некоторые действия создания индекса в миграцию, я не смогу правильно раскрутить новые базы данных.
Вот мое решение, некоторый код на Python для проверки существования индекса с использованием некоторых методов private-ish в 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)
]