Phuks-co / throat

Open Source link aggregator and discussion platform powering Phuks
https://phuks.co
MIT License
73 stars 32 forks source link

Fix migration problems #247

Closed happy-river closed 3 years ago

happy-river commented 3 years ago

We have a broken migration in the migration chain, 014_createreportlogs.py which was intended to create the tables for PostReportLog and CommentReportLog, the only difference between the two being the type of foreign key (sub_post_report vs sub_post_comment_report). In that migration, the table name for both tables is set to comment_report_log, so only one table gets created. A later migration creates the missing table but doesn't do anything to the existing one, which has its foreign key pointing to the wrong table.

This incorrect foreign key causes an "Unable to contact the server" error message if you try to add a note to a comment report when the index of that comment report is not a valid index into the post report table (as is likely for a recent comment report when the number of comment reports is greater than the number of post reports). Here's a backtrace from that event:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 3099, in execute_sql
cursor.execute(sql, params or ())
psycopg2.errors.ForeignKeyViolation: insert or update on table "comment_report_log" violates foreign key constraint "comment_report_log_id_fkey"
DETAIL: Key (id)=(234) is not present in table "sub_post_report".
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/dist-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.7/dist-packages/flask_login/utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "/throat/app/views/do.py", line 2660, in close_comment_report
misc.create_reportlog(misc.LOG_TYPE_REPORT_CLOSE, current_user.uid, id, type='comment')
File "/throat/app/misc.py", line 1450, in create_reportlog
CommentReportLog.create(action=action, uid=uid, id=id, desc=desc)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 6292, in create
inst.save(force_insert=True)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 6499, in save
pk = self.insert(**field_dict).execute()
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 1886, in inner
return method(self, database, *args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 1957, in execute
return self._execute(database)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 2707, in _execute
return super(Insert, self)._execute(database)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 2440, in _execute
cursor = self.execute_returning(database)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 2447, in execute_returning
cursor = database.execute(self)
File "/throat/app/models.py", line 94, in peewee_count_queries
return dex (*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 3112, in execute
return self.execute_sql(sql, params, commit=commit)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 3106, in execute_sql
self.commit()
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 2873, in __exit__
reraise(new_type, new_type(exc_value, *exc_args), traceback)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 183, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.7/dist-packages/peewee.py", line 3099, in execute_sql
cursor.execute(sql, params or ())
peewee.IntegrityError: insert or update on table "comment_report_log" violates foreign key constraint "comment_report_log_id_fkey"
DETAIL: Key (id)=(234) is not present in table "sub_post_report".

Fix this by adding two migrations to delete the comment_report_log table and recreate it, copying the data in and out of a temporary table.

In the process of working on this, I noticed that I had about 50 default wikis in my dev database. It turns out that our migration library runs all the old migrate functions with fake=True whenever you run a new migration or roll back a migration. I went through all the migrations and added checks so that they only do direct database operations when fake is not True.