Skip to content

Conversation

@Kyrela
Copy link
Contributor

@Kyrela Kyrela commented Aug 13, 2025

This PR adds the possibility to, on a colmun renaming when writing a migration, precise if the colmun is nullable or not, and the default value.

Why?

Because if I want to rename a nullable and null by default table, I actually can't:
The code

"""MyExample Migration."""

from masoniteorm.migrations import Migration


class MyExample (Migration):
    def up(self):
        """
        Run the migrations.
        """
        with self.schema.table("my_table") as table:
            table.rename("my_nullable_column", "my_renamed_column", "string", 255)

generates the SQL (at least when using MySQL)

 ALTER TABLE `my_table` CHANGE `my_nullable_column` `my_renamed_column` VARCHAR(255) NOT NULL

that results in

  QueryException

  (1265, "Data truncated for column 'my_nullable_column' at row 1")

  at .venv\Lib\site-packages\masoniteorm\connections\MySQLConnection.py:226 in query
      222│                     return self.format_cursor_results(cursor.fetchone())
      223│                 else:
      224│                     return self.format_cursor_results(cursor.fetchall())
      225│         except Exception as e:
    → 226│             raise QueryException(str(e)) from e
      227│         finally:
      228│             self._cursor.close()
      229│             if self.get_transaction_level() <= 0:
      230│                 self.open = 0

Because it tries to change a column where some values are actually NULL to a not null column.

How?

The best way for me to fix this issue is to make the migration fetch the table structure in the __enter__, instead of using False for the nullable attribute of the Column class by default. It would also remove the need to precise the column's length each time, so that's probably the simplest way for devs to use this.

Another okay option would be to make the nullable attribute of the Column class optionnal and None by default; this way, on rename, it would simply not be mentionned (it isn't required anyway for renaming) and the generated SQL would simply be

 ALTER TABLE `my_table` CHANGE `my_nullable_column` `my_renamed_column` VARCHAR(255)

Which is clearely better.

But I did neither. I looked at how it was working, and simply followed the way length is implemented. This method is pretty lame to use because you need to precise each time if your column is nullable and what is the default when you're renaming it, but, well:

  1. I don't want to invest too much time in this project, there would be too many problems which I stumbled upon to fix.
  2. It is still better than the current implementation, which, when it is actually working, forces the dev to write migrations like this:
    table.rename("reply", "reply_to_message", "boolean")
    table.boolean("reply_to_message").default(False).change()
    Because renaming a table is also resetting its properties.

@Kyrela Kyrela changed the base branch from 2.0 to 3.x November 9, 2025 16:07
@Kyrela Kyrela changed the base branch from 3.x to 2.0 November 9, 2025 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant