Caktus Group, a Django and Python development firm, blogs about Django, Celery, open source, and managing client projects.
Commenters call it a great technical blog on Python and Django. HN also links its post on why a clean git merge can still be wrong.
I’m a bit surprised to hear that is the state of migrations in Rails. Being a Django developer I’m used to having most of the points you mention covered for a really long time already.
It’s timeless by looking at a captured schema, that doesn’t change with later code changes. Which means you can’t import / use methods of models and have to copy those over. So a different way than using the vcs for this, but still.
Not sure I’d name the second point “scalable”, but you can easily do data migrations as well.
It is really easy to use!
And you can certainly write tests for it, although it isn’t included in the framework [0]. But you can do that with just SQL too [1].
What I find much harder with (somewhat) larger dbs, is is a) determining whether it will lock up too much and b) whether it backwards compatible (so that you can roll back). Which is splitting in these pre- and post-migration steps as the article mentions. We currently use a linter for that but it is still a bit basic [2].
[0] https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/
[1] https://tapoueh.org/blog/2017/08/sql-regression-tests/
[2] https://github.com/3YOURMIND/django-migration-linter
This is not specific to Django, but to any project using a database. Here's a list of a couple quite useful resources I used when we had to address this:
* https://github.com/tbicr/django-pg-zero-downtime-migrations
* https://docs.gitlab.com/development/migration_style_guide/
* https://pankrat.github.io/2015/django-migrations-without-downtimes/
* https://www.caktusgroup.com/blog/2021/05/25/django-migrations-and-deployment/
* https://openedx.atlassian.net/wiki/spaces/AC/pages/23003228/Everything+About+Database+Migrations
Generally it's also advisable to set a statement timeout for migrations otherwise you can end up with unintended downtime -- ALTER TABLE operations very often require ACCESS EXCLUSIVE lock, and if you're migrating a table that already has an e.g. very long SELECT operation from a background task on it, all other SELECTs will queue up behind the migration and cause request timeouts.
There are some cases you can work around this limitation by manually composing operations that require less strict locks, but in our case, it was much simpler to just make sure all Celery workers were stopped during migrations.
In RTP, since that's where I am:
https://www.caktusgroup.com/
http://www.redhat.com
https://www.sciencelogic.com/
https://www.ansible.com/
I moved from Python to JavaScript a few years ago primarily because the market just isn't there locally.
That OP is cherrypicking is obvious, but his web shop example is particularly brazen.
Google for 'django consulting' also turns up on first page:
http://www.comfychairconsulting.com/
http://tivix.com/
http://www.caktusgroup.com/
In git the rebase of course isn't a sound operation either, the merge is heuristic and you're liable to get conflicts or silent mismerges.
Some simple examples: https://www.caktusgroup.com/blog/2018/03/19/when-clean-merge-wrong/
The Caktus team has a great technical blog with many posts about Python and Django. I've also really enjoyed visiting with their people at PyCon over the years.
https://www.caktusgroup.com/blog/