nephila / djangocms-blog

django CMS blog application - Support for multilingual posts, placeholders, social network meta tags and configurable apphooks
https://djangocms-blog.readthedocs.io
BSD 3-Clause "New" or "Revised" License
391 stars 192 forks source link

correct M2M-primary-key-fields for updated 'default_auto_field' (INT -> BIGINT) #800

Open wfehr opened 2 months ago

wfehr commented 2 months ago

So we came across this very fancy problem because one of our projects ran into the "maximum INT"-value. -> we have to change our default_auto_field from AutoField to BigAutoField. With this update, the model-tables are changed - but the "through"-models for many-to-many-relationships aren't automatically.


Recently (via #741) the default_auto_field was changed from AutoField to BigAutoField in this project.

See django-docs: https://docs.djangoproject.com/en/dev/ref/settings/#default-auto-field

Unfortunately, the primary keys of existing auto-created through tables cannot currently be updated by the migrations framework.

This means that if you switch the value of DEFAULT_AUTO_FIELD and then generate migrations, the primary keys of the related models will be updated, as will the foreign keys from the through table, but the primary key of the auto-created through table will not be migrated.

In order to address this, you should add a RunSQL operation to your migrations to perform the required ALTER TABLE step. You can check the existing table name through sqlmigrate, dbshell, or with the field’s remote_field.through._meta.db_table property.


Example with post + categories (via Post.categories):

Theoretically you can have those relations in a high number which exceeds INT(11) and then results in a database error. The reason for this is the following database-setup of this project:

MySQL [myproject]> SELECT t.table_name, c.column_name, c.data_type
    -> FROM information_schema.tables t
    -> INNER JOIN information_schema.columns c
    ->   ON c.table_schema = t.table_schema AND c.table_name = t.table_name
    -> WHERE t.table_schema = 'myproject'
    ->   AND t.table_name LIKE "djangocms_blog%"
    -> ORDER BY t.auto_increment DESC;
+---------------------------------------------+-------------+-----------+
| table_name                                  | column_name | data_type |
+---------------------------------------------+-------------+-----------+
| djangocms_blog_post_related                 | id          | int       |
| djangocms_blog_post_categories              | id          | int       |
| djangocms_blog_post                         | id          | bigint    |
| djangocms_blog_post_translation             | id          | bigint    |
| djangocms_blog_blogcategory                 | id          | bigint    |
| djangocms_blog_blogcategory_translation     | id          | bigint    |
| djangocms_blog_blogconfig                   | id          | bigint    |
| djangocms_blog_post_sites                   | id          | int       |
| djangocms_blog_blogconfig_translation       | id          | bigint    |
| djangocms_blog_latestpostsplugin_categories | id          | int       |
| djangocms_blog_authorentriesplugin_authors  | id          | int       |
| djangocms_blog_featuredpostsplugin_posts    | id          | int       |
+---------------------------------------------+-------------+-----------+
12 rows in set (0.015 sec)

In order to avoid this possible error a new manually created migration is needed. This needs to adjust those "through-table"-primary-keys and set those to bigint as well.