Преглед изворни кода

Add migrations to remove indexes and alter field collations

Jeremy Stretch пре 3 месеци
родитељ
комит
a34553325e

+ 97 - 0
netbox/circuits/migrations/0053_ci_collations.py

@@ -0,0 +1,97 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'circuits_circuitgroup_name_ec8ac1e5_like',
+    'circuits_circuitgroup_slug_61ca866b_like',
+    'circuits_circuittype_name_8256ea9a_like',
+    'circuits_circuittype_slug_9b4b3cf9_like',
+    'circuits_provider_name_8f2514f5_like',
+    'circuits_provider_slug_c3c0aa10_like',
+    'circuits_virtualcircuittype_name_5184db16_like',
+    'circuits_virtualcircuittype_slug_75d5c661_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('circuits', '0052_extend_circuit_abs_distance_upper_limit'),
+        ('dcim', '0216_ci_collations'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='circuit',
+            name='cid',
+            field=models.CharField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='circuitgroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='circuitgroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='circuittype',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='circuittype',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='provider',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='provider',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='provideraccount',
+            name='account',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='provideraccount',
+            name='name',
+            field=models.CharField(blank=True, db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='providernetwork',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='virtualcircuit',
+            name='cid',
+            field=models.CharField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='virtualcircuittype',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='virtualcircuittype',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+    ]

+ 30 - 0
netbox/core/migrations/0020_ci_collations.py

@@ -0,0 +1,30 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'core_datasource_name_17788499_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0019_configrevision_active'),
+        ('dcim', '0216_ci_collations'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='datasource',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+    ]

+ 311 - 0
netbox/dcim/migrations/0217_ci_collations.py

@@ -0,0 +1,311 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'dcim_devicerole_slug_7952643b_like',
+    'dcim_devicetype_slug_448745bd_like',
+    'dcim_inventoryitemrole_name_4c8cfe6d_like',
+    'dcim_inventoryitemrole_slug_3556c227_like',
+    'dcim_location_slug_352c5472_like',
+    'dcim_manufacturer_name_841fcd92_like',
+    'dcim_manufacturer_slug_00430749_like',
+    'dcim_moduletypeprofile_name_1709c36e_like',
+    'dcim_platform_slug_b0908ae4_like',
+    'dcim_rackrole_name_9077cfcc_like',
+    'dcim_rackrole_slug_40bbcd3a_like',
+    'dcim_racktype_slug_6bbb384a_like',
+    'dcim_region_slug_ff078a66_like',
+    'dcim_site_name_8fe66c76_like',
+    'dcim_site_slug_4412c762_like',
+    'dcim_sitegroup_slug_a11d2b04_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ('dcim', '0216_ci_collations'),
+        ('extras', '0134_ci_collations'),
+        ('ipam', '0083_ci_collations'),
+        ('tenancy', '0021_ci_collations'),
+        ('virtualization', '0048_populate_mac_addresses'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.RemoveConstraint(
+            model_name='device',
+            name='dcim_device_unique_name_site_tenant',
+        ),
+        migrations.RemoveConstraint(
+            model_name='device',
+            name='dcim_device_unique_name_site',
+        ),
+        migrations.AlterField(
+            model_name='consoleport',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='consoleporttemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='consoleserverport',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='consoleserverporttemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='device',
+            name='name',
+            field=models.CharField(blank=True, db_collation='ci_natural_sort', max_length=64, null=True),
+        ),
+        migrations.AlterField(
+            model_name='devicebay',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='devicebaytemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='devicerole',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='devicerole',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='devicetype',
+            name='model',
+            field=models.CharField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='devicetype',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='frontport',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='frontporttemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='interface',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='interfacetemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='inventoryitem',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='inventoryitemrole',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='inventoryitemrole',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='inventoryitemtemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='location',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='location',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='manufacturer',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='manufacturer',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='modulebay',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='modulebaytemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='moduletype',
+            name='model',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='moduletypeprofile',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='platform',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='platform',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='powerfeed',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='poweroutlet',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='poweroutlettemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='powerpanel',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='powerport',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='powerporttemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='rack',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='rackrole',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='rackrole',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='racktype',
+            name='model',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='racktype',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='rearport',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='rearporttemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='region',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='region',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='site',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='site',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='sitegroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='sitegroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='virtualdevicecontext',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AddConstraint(
+            model_name='device',
+            constraint=models.UniqueConstraint(
+                models.F('name'), models.F('site'), models.F('tenant'), name='dcim_device_unique_name_site_tenant'
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name='device',
+            constraint=models.UniqueConstraint(
+                models.F('name'),
+                models.F('site'),
+                condition=models.Q(('tenant__isnull', True)),
+                name='dcim_device_unique_name_site',
+                violation_error_message='Device name must be unique per site.',
+            ),
+        ),
+    ]

+ 114 - 0
netbox/extras/migrations/0134_ci_collations.py

@@ -0,0 +1,114 @@
+import django.core.validators
+import re
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'extras_configcontext_name_4bbfe25d_like',
+    'extras_configcontextprofile_name_070de83b_like',
+    'extras_customfield_name_2fe72707_like',
+    'extras_customfieldchoiceset_name_963e63ea_like',
+    'extras_customlink_name_daed2d18_like',
+    'extras_eventrule_name_899453c6_like',
+    'extras_notificationgroup_name_70b0a3f9_like',
+    'extras_savedfilter_name_8a4bbd09_like',
+    'extras_savedfilter_slug_4f93a959_like',
+    'extras_tag_name_9550b3d9_like',
+    'extras_tag_slug_aaa5b7e9_like',
+    'extras_webhook_name_82cf60b5_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ('extras', '0133_make_cf_minmax_decimal'),
+        ('dcim', '0216_ci_collations'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='configcontext',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='configcontextprofile',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='customfield',
+            name='name',
+            field=models.CharField(
+                db_collation='ci_natural_sort',
+                max_length=50,
+                unique=True,
+                validators=[
+                    django.core.validators.RegexValidator(
+                        flags=re.RegexFlag['IGNORECASE'],
+                        message='Only alphanumeric characters and underscores are allowed.',
+                        regex='^[a-z0-9_]+$',
+                    ),
+                    django.core.validators.RegexValidator(
+                        flags=re.RegexFlag['IGNORECASE'],
+                        inverse_match=True,
+                        message='Double underscores are not permitted in custom field names.',
+                        regex='__',
+                    ),
+                ],
+            ),
+        ),
+        migrations.AlterField(
+            model_name='customfieldchoiceset',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='customlink',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='eventrule',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=150, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='notificationgroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='savedfilter',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='savedfilter',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tag',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tag',
+            name='slug',
+            field=models.SlugField(allow_unicode=True, db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='webhook',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=150, unique=True),
+        ),
+    ]

+ 100 - 0
netbox/ipam/migrations/0083_ci_collations.py

@@ -0,0 +1,100 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'ipam_asnrange_name_c7585e73_like',
+    'ipam_asnrange_slug_c8a7d8a1_like',
+    'ipam_rir_name_64a71982_like',
+    'ipam_rir_slug_ff1a369a_like',
+    'ipam_role_name_13784849_like',
+    'ipam_role_slug_309ca14c_like',
+    'ipam_routetarget_name_212be79f_like',
+    'ipam_servicetemplate_name_1a2f3410_like',
+    'ipam_vlangroup_slug_40abcf6b_like',
+    'ipam_vlantranslationpolicy_name_17e0a007_like',
+    'ipam_vrf_rd_0ac1bde1_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ipam', '0082_add_prefix_network_containment_indexes'),
+        ('dcim', '0216_ci_collations'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='asnrange',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='asnrange',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='rir',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='rir',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='role',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='role',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='routetarget',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=21, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='servicetemplate',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='vlan',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='vlangroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='vlangroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='vlantranslationpolicy',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='vrf',
+            name='rd',
+            field=models.CharField(blank=True, db_collation='case_insensitive', max_length=21, null=True, unique=True),
+        ),
+    ]

+ 70 - 0
netbox/tenancy/migrations/0021_ci_collations.py

@@ -0,0 +1,70 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'tenancy_contactgroup_slug_5b0f3e75_like',
+    'tenancy_contactrole_name_44b01a1f_like',
+    'tenancy_contactrole_slug_c5837d7d_like',
+    'tenancy_tenant_slug_0716575e_like',
+    'tenancy_tenantgroup_name_53363199_like',
+    'tenancy_tenantgroup_slug_e2af1cb6_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tenancy', '0020_remove_contactgroupmembership'),
+        ('dcim', '0216_ci_collations'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='contactgroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='contactgroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='contactrole',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='contactrole',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tenant',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='tenant',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='tenantgroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tenantgroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+    ]

+ 92 - 0
netbox/virtualization/migrations/0049_ci_collations.py

@@ -0,0 +1,92 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'virtualization_clustergroup_name_4fcd26b4_like',
+    'virtualization_clustergroup_slug_57ca1d23_like',
+    'virtualization_clustertype_name_ea854d3d_like',
+    'virtualization_clustertype_slug_8ee4d0e0_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ('dcim', '0217_ci_collations'),
+        ('extras', '0134_ci_collations'),
+        ('ipam', '0083_ci_collations'),
+        ('tenancy', '0021_ci_collations'),
+        ('virtualization', '0048_populate_mac_addresses'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.RemoveConstraint(
+            model_name='virtualmachine',
+            name='virtualization_virtualmachine_unique_name_cluster_tenant',
+        ),
+        migrations.RemoveConstraint(
+            model_name='virtualmachine',
+            name='virtualization_virtualmachine_unique_name_cluster',
+        ),
+        migrations.AlterField(
+            model_name='cluster',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100),
+        ),
+        migrations.AlterField(
+            model_name='clustergroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='clustergroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='clustertype',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='clustertype',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='virtualdisk',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='virtualmachine',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=64),
+        ),
+        migrations.AddConstraint(
+            model_name='virtualmachine',
+            constraint=models.UniqueConstraint(
+                models.F('name'),
+                models.F('cluster'),
+                models.F('tenant'),
+                name='virtualization_virtualmachine_unique_name_cluster_tenant',
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name='virtualmachine',
+            constraint=models.UniqueConstraint(
+                models.F('name'),
+                models.F('cluster'),
+                condition=models.Q(('tenant__isnull', True)),
+                name='virtualization_virtualmachine_unique_name_cluster',
+                violation_error_message='Virtual machine name must be unique per cluster.',
+            ),
+        ),
+    ]

+ 84 - 0
netbox/vpn/migrations/0010_ci_collations.py

@@ -0,0 +1,84 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'vpn_ikepolicy_name_5124aa3b_like',
+    'vpn_ikeproposal_name_254623b7_like',
+    'vpn_ipsecpolicy_name_cf28a1aa_like',
+    'vpn_ipsecprofile_name_3ac63c72_like',
+    'vpn_ipsecproposal_name_2fb98e2b_like',
+    'vpn_l2vpn_name_8824eda5_like',
+    'vpn_l2vpn_slug_76b5a174_like',
+    'vpn_tunnel_name_f060beab_like',
+    'vpn_tunnelgroup_name_9f6ebf92_like',
+    'vpn_tunnelgroup_slug_9e614d62_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0216_ci_collations'),
+        ('vpn', '0009_remove_redundant_indexes'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='ikepolicy',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='ikeproposal',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='ipsecpolicy',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='ipsecprofile',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='ipsecproposal',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='l2vpn',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='l2vpn',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tunnel',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tunnelgroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='tunnelgroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+    ]

+ 36 - 0
netbox/wireless/migrations/0016_ci_collations.py

@@ -0,0 +1,36 @@
+from django.db import migrations, models
+
+PATTERN_OPS_INDEXES = [
+    'wireless_wirelesslangroup_name_2ffd60c8_like',
+    'wireless_wirelesslangroup_slug_f5d59831_like',
+]
+
+
+def remove_indexes(apps, schema_editor):
+    for idx in PATTERN_OPS_INDEXES:
+        schema_editor.execute(f'DROP INDEX IF EXISTS {idx}')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0216_ci_collations'),
+        ('wireless', '0015_extend_wireless_link_abs_distance_upper_limit'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            code=remove_indexes,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.AlterField(
+            model_name='wirelesslangroup',
+            name='name',
+            field=models.CharField(db_collation='ci_natural_sort', max_length=100, unique=True),
+        ),
+        migrations.AlterField(
+            model_name='wirelesslangroup',
+            name='slug',
+            field=models.SlugField(db_collation='case_insensitive', max_length=100, unique=True),
+        ),
+    ]