【问题标题】:how to add db_index=True to email field of django auth_user如何将 db_index=True 添加到 django auth_user 的电子邮件字段
【发布时间】:2015-08-28 11:24:40
【问题描述】:

突然间,我的页面在 db 中获得了如此多的用户,以至于 auth_user 表上的电子邮件过滤器几乎由于用户数量众多而失败。

由于表格是内置的,我需要将db_index=True 添加到此表格的列中,知道该怎么做吗?

【问题讨论】:

    标签: django django-models django-authentication


    【解决方案1】:

    一种可能性是将用户模型替换为自定义模型,该模型将具有适当的索引和您需要的任何其他字段。在Django docs: Substituting a custom User model 上有大量关于如何实现这一点的文档。这就是我在具有类似问题的特定案例中的做法。

    另一种可能性是extend the user model,它可能有一个从原始模型重复的特定字段,在该字段上有一个索引。 免责声明:出于显而易见的原因,我真的反对这种做法,但我已经看到这种情况发生了,因为这种方法比第一种方法更容易编码。如果有很多字段,这将是非常糟糕的。

    这是一个很好的问题。我很想知道是否还有其他我想念的可能性。

    【讨论】:

    • 谢谢,上面的技术我很熟悉,但是我很想有一些不需要换桌子等的方法。因为我的桌子现在太大了,我宁愿不碰它的结构..但我继续寻找更好的解决方案..让我们听听其他人的想法;)
    • 欢迎您,我以为您会很熟悉,但我会保留答案以作记录。
    【解决方案2】:

    一种快速简便的方法是在迁移中使用RunSQL 手动添加索引。

    operations = [
        migrations.RunSQL("CREATE INDEX..."),
    ]
    

    它不是很优雅。一方面,迁移将针对不同的应用程序(因为您无法控制 auth 迁移)。另一方面,模式在技术上将与数据库不同步。但是,我认为在这种情况下不会有任何负面影响,因为 Django 除了创建索引之外,不会对 db_index 做任何事情。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,但有一个额外的转折——我的表中已经有一个由 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)
          ]
      

      【讨论】:

      • 一个更简单的解决方案是创建 RunSQL 迁移,然后将其假应用(参见 here)到现有数据库。
      • 当然我的解决方案是更多的代码,但是做你的就是更多的操作工作,并且有一些机会横盘整理。这是一个偏好问题。
      猜你喜欢
      • 1970-01-01
      • 2013-01-25
      • 2017-08-27
      • 2013-10-19
      • 1970-01-01
      • 2017-05-20
      • 2012-12-26
      • 1970-01-01
      • 2016-04-17
      相关资源
      最近更新 更多