I'm trying to configure Django models with a legacy database. After running inspectdb
I've started going through the recommended basic clean up steps (ie rearrange models' order, make sure each model has a primary key, foreign keys 'on delete', etc.). I've decided to keep managed = False
in class Meta
in each model to avoid migration issues with legacy app that it may cause.
In addition to the basic cleanup steps I'm wondering if it's recommended or necessary at all to add models.Index
and models.UniqueConstraints
to class Meta
for my tables that already have these indexes and constraints defined in the database. Are these specific (class Meta) settings only needed for migrations or does Django use them to enforce constraints and for indexing at the app level in addition to what my database server (mysql 5.7) already is designed to do?
For example, here's a table with an index on a column named 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
So is it necessary to define meta Class
with something like:
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')
]
Or if a table has a unique constraint like this:
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
Is it necessary to define meta Class with something like:
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')
]
CodePudding user response:
Is it necessary ...
No.
Is there any point in defining ...
Yes and no, in addition to functioning as hints to other developers.
Indexes
Options: indexes
/ index_together
Not at runtime. This is only used in two places:
-
- Commands:
makemigrations
,migrate
- Commands:
-
- Command:
check
- Command:
Unique constraints
Options: constraints
/ unique_together
Yes. In addition to the two places that indexes are used, this is also used in:
- Form and field validation → Model instance reference - django.db.models.Model.validate_unique
- Call chain:
form.is_valid()
→form.full_clean()
→ ... →self.instance.validate_unique()
- Call chain: