如果 managed = False,在 Django 模型的 class Meta 中定义 models.Index 或 models.UniqueConstraint 是否有任何意义

Is there any point in defining models.Index or models.UniqueConstraint in class Meta of a Django Model, if managed = False

我正在尝试使用遗留数据库配置 Django 模型。在 运行 inspectdb 之后,我开始执行推荐的基本清理步骤(即重新排列模型的顺序,确保每个模型都有主键、外键 'on delete' 等) .我决定在每个模型中将 managed = False 保留在 class Meta 中,以避免它可能导致的遗留应用程序迁移问题。

除了基本的清理步骤之外,我想知道是否推荐或有必要为我的 table 添加 models.Indexmodels.UniqueConstraintsclass Meta已经在数据库中定义了这些索引和约束。这些特定的(class Meta)设置是否仅在迁移时需要,或者除了我的数据库服务器(mysql 5.7)已经设计的之外,Django 是否使用它们来强制约束和在应用程序级别建立索引做什么?

例如,这里有一个 table,在名为 PAYMENT_METHOD:

的列上有一个索引
accounts | CREATE TABLE `accounts` (
  `ACCOUNT_NUMBER` int(11) NOT NULL,
  `ACCOUNT_NAME` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `PAYMENT_METHOD` int(11) DEFAULT NULL,
  `FLAGGED` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`ACCOUNT_NUMBER`),
  KEY `a_pm_ix` (`PAYMENT_METHOD`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

那么是否有必要定义 meta Class 为:

class Accounts(models.Model):
    account_number = models.IntegerField(db_column='ACCOUNT_NUMBER', primary_key=True)  
    account_name = models.CharField(db_column='ACCOUNT_NAME', max_length=40, blank=True, null=True)  
    payment_method = models.IntegerField(db_column='PAYMENT_METHOD', blank=True, null=True)  
    flagged = models.BooleanField(db_column='FLAGGED', blank=True, null=True)  

    class Meta:
        managed = False
        app_label = 'schoolsys'
        db_table = 'accounts'
        indexes = [
            models.Index(fields=['PAYMENT_METHOD'], name='payment_method_idx')
        ]

或者如果 table 有这样的唯一约束:

system_users | CREATE TABLE `system_users` (
  `USER_ID` int(11) NOT NULL,
  `USER_NAME` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `PASSWORD` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `MGR_CODE` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `IS_ADMIN` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`USER_ID`),
  UNIQUE KEY `USER_NAME` (`USER_NAME`),
  KEY `su_un_ix` (`USER_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

是否有必要定义 meta Class 为:

class SystemUsers(models.Model):
    user_id = models.IntegerField(db_column='USER_ID', primary_key=True)  
    user_name = models.CharField(db_column='USER_NAME', unique=True, max_length=20, blank=True, null=True)  
    password = models.CharField(db_column='PASSWORD', max_length=40, blank=True, null=True)  
    mgr_code = models.CharField(db_column='MGR_CODE', max_length=20, blank=True, null=True)  
    is_admin = models.BooleanField(db_column='IS_ADMIN', blank=True, null=True)

    class Meta:
        managed = False
        app_label = 'schoolsys'
        db_table = 'system_users'
        constraints = [
            models.UniqueConstraint(fields=['USER_NAME'], name='unique_username')
        ]        
        indexes = [
            models.Index(fields=['USER_NAME'], name='user_name_idx')
        ]
        

Is it necessary ...

没有

Is there any point in defining ...

是和否,除了作为对其他开发人员的提示。

索引

选项:indexes / index_together

不是在运行时。这只用在两个地方:

  1. Migrations

  2. Checks - Models

唯一约束

选项:constraints / unique_together

是的。除了用到索引的两个地方,这个还用在了:

  1. Form and field validationModel instance reference - django.db.models.Model.validate_unique
    • 调用链:form.is_valid()form.full_clean() → ... → self.instance.validate_unique()