Как добавить 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)
    ]
Другие вопросы по тегам