4

使用models.varchar(...)字段创建模型时,正在创建varchar_pattern_ops索引。如何在django(1.8)迁移中删除index varchar_pattern_ops?

这是我想删除varchar_pattern_ops指数在迁移,并且在该领域中添加散列索引PostgreSQL中

   Table "public.logger_btilog" 
     Column  |   Type   | Modifiers 
------------------+--------------------------+----------- 
md5hash   | text      | 
id    | integer     | not null 
Indexes: 
    "logger_btilog_pkey" PRIMARY KEY, btree (id) 
    "logger_btilog_md5hash_6454d7bb20588b61_like" btree (md5hash varchar_pattern_ops) 

生成的表。

我试着这样做:

# models.py 
class Btilog(models.Model): 
    md5hash = models.TextField(db_index=False) 
    [...] 

而且在迁移也迫使加db_field=False

# 0013_migration.py 
# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import models, migrations 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('logger', '0014_btilog_id'), 
    ] 

    operations = [ 
     # this should remove all indexes for md5hash, but it does not work 
     migrations.AlterField(
      model_name='btilog', 
      name='md5hash', 
      field=models.TextField(null=True, blank=True, db_index=False), 
     ), 
     migrations.RunSQL(
      "create index logger_btilog_md5hash_hashindex on logger_btilog using hash(md5hash);", 
      "drop index logger_btilog_md5hash_hashindex;" 
     ), 
] 

运行迁移后,这是在数据库

       relation        | size 
--------------------------------------------------------------------+--------- 
public.logger_btilog            | 7185 MB 
public.logger_btilog_md5hash_6454d7bb20588b61_like     | 1442 MB 
public.logger_btilog_md5hash_hashindex        | 1024 MB 
public.logger_btilog_pkey           | 548 MB 

注意索引public.logger_btilog_md5hash_6454d7bb20588b61_like是我想要删除的索引。正在Django的自动添加该指数,看this

更多信息对指数

vtfx=# \d logger_btilog_md5hash_6454d7bb20588b61_like 
Index "public.logger_btilog_md5hash_6454d7bb20588b61_like" 
Column | Type | Definition 
---------+------+------------ 
md5hash | text | md5hash 
btree, for table "public.logger_btilog" 

脚注:我不会混乱哈希索引的使用,我只希望做=(strictrly相等)where搜索在md5hash字段,然后(随便)一hash指数将是最快,将占据超过btree指数更少的空间(Django默认)

+0

你知道散列索引不会崩溃,安全,不会被复制,对不对? –

+0

不,我没有......谢谢你指出,我会更多地阅读。不过,问题在于其他索引删除。 – jperelli

回答

7

好吧,我发现这里的一些信息https://docs.djangoproject.com/en/1.8/_modules/django/db/backends/base/schema/#BaseDatabaseSchemaEditor.alter_field

并采用人工RunPython迁移删除varchar_pattern_ops指数使用SchemaEditor

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import models, migrations 


import re 
def drop_md5hash_varchar_pattern_ops_index(apps, schemaEditor): 
    # code based on https://docs.djangoproject.com/en/1.8/_modules/django/db/backends/base/schema/#BaseDatabaseSchemaEditor.alter_field 
    model = apps.get_model("logger", "Btilog") 
    index_names = schemaEditor._constraint_names(model, index=True) 
    for index_name in index_names: 
     if re.search('logger_btilog_md5hash_.+_like', index_name): 
      print 'dropping index {}'.format(index_name) 
      schemaEditor.execute(schemaEditor._delete_constraint_sql(schemaEditor.sql_delete_index, model, index_name)) 


class Migration(migrations.Migration): 
    dependencies = [ 
     ('logger', '0012_auto_20150529_1745'), 
    ] 

    operations = [ 
     # Remove the annoying index using a hack 
     migrations.RunPython(
      drop_md5hash_varchar_pattern_ops_index 
     ), 
    ]