Django:创建索引:非唯一,多列

jba*_*tos 28 mysql django indexing

鉴于以下模型,我想索引字段(序列,库存)

class QuoteModel(models.Model):  
    quotedate =  models.DateField()  
    high = models.FloatField() #(9,2) DEFAULT NULL,  
    low  = models.FloatField() #(9,2) DEFAULT NULL,  
    close  = models.FloatField() #(9,2) DEFAULT NULL,  
    closeadj  = models.FloatField() #(9,2) DEFAULT NULL,  
    volume  = models.IntegerField() #(9,2) DEFAULT NULL,  
    stock  = models.IntegerField(db_index=True) #(9,2) DEFAULT NULL,  
    open  = models.FloatField() #(9,2) DEFAULT NULL,  
    sequence = models.IntegerField() #(9,2) DEFAULT NULL,  
Run Code Online (Sandbox Code Playgroud)

这个索引应该是非唯一的 - 在mysql中它应该是这样的:

create index ndx_1 on model_quotemodel(sequence,stock);
Run Code Online (Sandbox Code Playgroud)

我所知道的唯一的Django解决方法是创建一个"sql"文件,该文件将在创建表时由django执行.所以,我创建了一个包含以下查询的"stockmodel.sql"(与上面相同:)

create index ndx_1 on model_quotemodel(sequence,stock);
Run Code Online (Sandbox Code Playgroud)

这样做有"更干净"的方法吗?

Iva*_*yan 21

这个功能有一张票.看看http://code.djangoproject.com/ticket/5805

您可以自己应用此票证中的补丁.

UPDATE

它现在在Django:https://docs.djangoproject.com/en/1.5/ref/models/options/#django.db.models.Options.index_together


exc*_*eve 18

从Django 1.5开始,您可以使用以下Meta.index_together选项:

class QuoteModel(models.Model):
    # ... fields ...

    class Meta:
        index_together = [
            ("sequence", "stock"),
        ]
Run Code Online (Sandbox Code Playgroud)

(注意:2009年的原始答案说不可能索引多个字段;它已被替换)

  • 我不确定这个答案是否真正解决了非主键复合键?似乎没有. (2认同)
  • 这根本不是问题所在.需要非唯一的非主要复合键. (2认同)

Geo*_*und 16

要从接受的答案中继续,如果您使用的是South,则可以轻松添加复合键,如下所示:

manage.py schemamigration your_app_name name_for_migration --add-index ModelName.first_field_in_index

然后,您可以编辑生成的迁移文件,将其他字段添加到一个索引中(您将看到它只是一个需要的字段名称列表).

不要忘记更新反向迁移以及前向迁移.


cas*_*ere 14

在django 1.5中它是index_together

在这里看到https://docs.djangoproject.com/en/dev/ref/models/options/#index-together


cra*_*esh 10

unique_together可能就是你要找的东西.只需将它Meta放在模型中的类中即可.

  • 他要求index_together.你告诉他unique_together.不是他问的. (5认同)
  • 虽然这不是这个问题的答案,但这有助于我完全搜索多列唯一索引.所以,无论如何,谢谢 (2认同)

Sam*_*zon 5

The index_together feature could be deprecated in the futur.

You should use indexes option instead of index_together.

Example of indexes option :

from django.db import models

class Customer(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=['last_name', 'first_name']),
            models.Index(fields=['first_name'], name='first_name_idx'),
        ]
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 5

2022 年更新:

较新的indexes选项提供了比index_together. index_together 在 Django 4.1 中已弃用

用法

from django.db import models

class Customer(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=['last_name', 'first_name']),
            models.Index(fields=['first_name'], name='first_name_idx'),
        ]
Run Code Online (Sandbox Code Playgroud)