Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linter fails on CREATE INDEX when creating a new table #178

Closed
phillipuniverse opened this issue Nov 2, 2021 · 0 comments · Fixed by #186
Closed

Linter fails on CREATE INDEX when creating a new table #178

phillipuniverse opened this issue Nov 2, 2021 · 0 comments · Fixed by #186
Assignees

Comments

@phillipuniverse
Copy link
Contributor

Here is an example CreateModel from Django:

migrations.CreateModel(
    name='ShipmentMetadataAlert',
    fields=[
        ('deleted_at', models.DateTimeField(blank=True, db_index=True, null=True)),
        ('created_at', common.fields.CreatedField(default=django.utils.timezone.now, editable=False)),
        ('updated_at', common.fields.LastModifiedField(default=django.utils.timezone.now, editable=False)),
        ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')),
        ('message', models.TextField(blank=True, null=True)),
        ('level', models.CharField(blank=True, choices=[('HIGH', 'high'), ('MEDIUM', 'medium'), ('LOW', 'low')], max_length=16, null=True)),
        ('type', models.CharField(blank=True, choices=[('MOBILE_DEVICE_ALERT', 'MOBILE_DEVICE_ALERT'), ('NON_ACTIVE_CARRIER', 'NON_ACTIVE_CARRIER'), ('OTHER', 'OTHER')], max_length=32, null=True)),
        ('subtype', models.CharField(blank=True, choices=[('DRIVER_PERMISSIONS', 'DRIVER_PERMISSIONS'), ('DRIVER_LOCATION', 'DRIVER_LOCATION'), ('OTHER', 'OTHER')], max_length=32, null=True)),
        ('occurred_at', models.DateTimeField(null=True)),
        ('clear_alert_job_id', models.UUIDField(default=None, null=True)),
        ('metadata', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='alerts', to='shipments.ShipmentMetadata')),
    ],
    options={
        'abstract': False,
    }
)

Here are the SQL statements that this spits out in sqlmigrate:

BEGIN;
--
-- Create model ShipmentMetadataAlert
--
CREATE TABLE "shipments_shipmentmetadataalert" ("deleted_at" timestamp with time zone NULL, "created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL, "id" uuid NOT NULL PRIMARY KEY, "message" text NULL, "level" varchar(16) NULL, "type" varchar(32) NULL, "subtype" varchar(32) NULL, "occurred_at" timestamp with time zone NULL, "clear_alert_job_id" uuid NULL, "metadata_id" uuid NOT NULL);
ALTER TABLE "shipments_shipmentmetadataalert" ADD CONSTRAINT "shipments_shipmentme_metadata_id_f20850e8_fk_shipments" FOREIGN KEY ("metadata_id") REFERENCES "shipments_shipmentmetadata" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "shipments_shipmentmetadataalert_deleted_at_c9a93342" ON "shipments_shipmentmetadataalert" ("deleted_at");
CREATE INDEX "shipments_shipmentmetadataalert_metadata_id_f20850e8" ON "shipments_shipmentmetadataalert" ("metadata_id");
COMMIT;

This is an error from the linter as it outputs the error CREATE INDEX locks table. But the table is being created within the migration, it just needs to recognize that.

It seems like the CREATE INDEX detection should work the same way that the ADD_UNIQUE detection works where it detects that the create table is happening in the same migration:

def has_add_unique(sql_statements, **kwargs):
regex_result = None
for sql in sql_statements:
regex_result = re.search("ALTER TABLE (.*) ADD CONSTRAINT .* UNIQUE", sql)
if regex_result:
break
if not regex_result:
return False
concerned_table = regex_result.group(1)
table_is_added_in_transaction = any(
sql.startswith("CREATE TABLE {}".format(concerned_table))
for sql in sql_statements
)
return not table_is_added_in_transaction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants