Skip to content

Commit

Permalink
user: migrating to serial user ID #19
Browse files Browse the repository at this point in the history
  • Loading branch information
thomersch committed May 16, 2020
1 parent 0526c3c commit 7890094
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
61 changes: 61 additions & 0 deletions osmcal/migrations/0023_user_primary_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from django.db import migrations, models

"""
Hi! I made this because I can't stop making the same mistake: Never use a third-party ID as foreign
key, because every change will be painful. I am fixing this mistake here: We're going to walk over
all tables that reference osmcal_user.osm_id and replace this with a serial id.
This involves a little bit of fiddling, as you might see.
"""

user_id_dependent_tables = [
("osmcal_eventlog", "created_by_id", "osmcal_eventlog_created_by_id_89c62fed_fk_osmcal_user_osm_id"),
("osmcal_eventparticipation", "user_id", "osmcal_eventparticip_user_id_8a2dfe0f_fk_osmcal_us"),
("osmcal_participationanswer", "user_id", "osmcal_participation_user_id_93228060_fk_osmcal_us"),
("osmcal_user_groups", "user_id", "osmcal_user_groups_user_id_c9d0a3d1_fk_osmcal_user_osm_id"),
("osmcal_user_user_permissions", "user_id", "osmcal_user_user_per_user_id_1ecd1641_fk_osmcal_us"),
("django_admin_log", "user_id", "django_admin_log_user_id_c564eba6_fk_osmcal_user_osm_id"),
]


def conversion_sql():
sql = ""
for t in user_id_dependent_tables:
sql += """
ALTER TABLE {0} DROP CONSTRAINT {2};
UPDATE {0} SET {1} = (SELECT id FROM osmcal_user WHERE osm_id = {0}.{1});
ALTER TABLE {0} ADD CONSTRAINT {2} FOREIGN KEY ({1}) REFERENCES osmcal_user (id);
""".format(*t)
return sql


class Migration(migrations.Migration):

dependencies = [
('osmcal', '0022_event_cancelled'),
]

operations = [
migrations.SeparateDatabaseAndState(
database_operations=[
migrations.RunSQL([
'ALTER TABLE osmcal_user ADD column id serial UNIQUE;',
conversion_sql(),
'ALTER TABLE osmcal_user DROP CONSTRAINT osmcal_user_pkey;',
'ALTER TABLE osmcal_user ADD PRIMARY KEY (id);',
])
],
state_operations=[
migrations.AddField(
model_name='user',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
preserve_default=False,
),
migrations.AlterField(
model_name='user',
name='osm_id',
field=models.IntegerField(),
),
]
)
]
3 changes: 2 additions & 1 deletion osmcal/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ class EventLog(models.Model):


class User(AbstractUser):
osm_id = models.IntegerField(primary_key=True)
id = models.AutoField(primary_key=True)
osm_id = models.IntegerField()
name = models.CharField(max_length=255)

def save(self, *args, **kwargs):
Expand Down

0 comments on commit 7890094

Please sign in to comment.