why django makemigration command creates python based code instead of creating sql commands, Someone please explain from design decision point of view, and what benefits we get from it.
Because Django aims (and to some extent succeeds) to be dialect-invariant, and even does not require an SQL database.
Indeed, the DATABASES
setting [Django-doc] setting allows to specify the backend, and the builtin backends are different dialects of SQL, but Djongo [pypi.org] for example even aims to let this work with a MongoDB database.
The dialects are also not consistent for advanced features. For example PostgreSQL matches regexes with the ~
operator, whereas SQLite uses the REGEXP
operator.
But even if we manage to find a common syntax, there are other reasons why this is a bad idea: the migrations do not only generate SQL commands, they also explain what has changed up to a the (most recent) migration. This is what Django itself uses if you run makemigration
[Django-doc] to inspect the "diff" and thus generate new migration files. If we would use SQL we somehow need to find a way to "parse" the SQL and understand the impact, so we "lose" context.
A lot of migrations can also get reverted, you can migrate the system to the state of a certain migration file. Django will then, if possible, reverse the migrations. For example if you changed a VARCHAR(42)
to a VARCHAR(69)
, it will again alter it back to a VARCHAR(42)
.
Django's migrations do not per see add fields or remove tables, but also include data migrations [Django-doc] where you run a custom Python function that can for example insert records.
We thus can summarize this as Django's migration files are "richer" and provide more context than SQL commands. The framework can understand what it is doing, not that much how.