Skip to content

Changing column to a foreign key in auto migration causes an exception #1301

@gsavchuk

Description

@gsavchuk

Piccolo version 1.30
I tried to change the client field from
client = Integer(null=True)
to
client = ForeignKey(Client, target_column=Client.client_id, on_delete=OnDelete.restrict)

Generated the auto migration and it failed while running:

...
  File "/usr/local/lib/python3.12/site-packages/piccolo/apps/migrations/commands/forwards.py", line 122, in run_forwards
    response = await manager.run()
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/piccolo/apps/migrations/commands/forwards.py", line 99, in run
    return await self.run_migrations(app_config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/piccolo/apps/migrations/commands/forwards.py", line 83, in run_migrations
    await response.run()
  File "/usr/local/lib/python3.12/site-packages/piccolo/apps/migrations/auto/migration_manager.py", line 1010, in run
    await self._run_alter_columns(backwards=backwards)
  File "/usr/local/lib/python3.12/site-packages/piccolo/apps/migrations/auto/migration_manager.py", line 546, in _run_alter_columns
    constraint_name = await get_fk_constraint_name(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/piccolo/query/constraints.py", line 43, in get_fk_constraint_name
    return constraints[0]["fk_constraint_name"]
           ~~~~~~~~~~~^^^
IndexError: list index out of range

This is because of the assumption that if a column is ForeignKey, than there is an existing FK constraint, which is not true in this case.

The generated auto-migration snippet:

    manager.alter_column(
        table_class_name="Temp",
        tablename="temp",
        column_name="client",
        db_column_name="client",
        params={
            "references": Client,
            "on_delete": OnDelete.restrict,
            "on_update": OnUpdate.cascade,
            "target_column": "client_id",
        },
        old_params={
            "references": None,
            "on_delete": None,
            "on_update": None,
            "target_column": None,
        },
        column_class=ForeignKey,
        old_column_class=Integer,
        schema=None,
    )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions