-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eef63df
commit 9ba1dc9
Showing
13 changed files
with
168 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
.../slack/migrations/0009_drop_orphaned_messages_and_fill_in_missing_team_identity_values.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# Generated by Django 4.2.16 on 2024-12-04 21:17 | ||
|
||
import logging | ||
|
||
from django.db import migrations | ||
from django.db.models import Subquery, OuterRef | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def drop_orphaned_slack_messages(apps, schema_editor): | ||
""" | ||
At this point, in the 0007_migrate_slackmessage_channel_id migration, we have already migrated the old | ||
SlackMessage._channel_id (char field) to the new SlackMessage.channel_id (FK field). | ||
This script is needed to identity, and drop, SlackMessage records that are "orphaned". This would've occured in two | ||
cases: | ||
- the organization switched their Slack team identity. We have historically never done clean-up of the old SlackMessage records | ||
- a Slack channel was deleted. Previously, we did not have a FK constraint on the SlackMessage._channel_id | ||
char field, so there was no CASCADE delete behaviour (now there is). | ||
In both of these scenarios, the SlackMessage records would be "orphaned" - they would have a non-null channel_id | ||
foreign key relationship, which prevents us from setting NOT NULL constraint on the channel_id field. | ||
""" | ||
SlackMessage = apps.get_model("slack", "SlackMessage") | ||
|
||
logger.info("Starting migration to drop orphaned SlackMessage records.") | ||
|
||
slack_messages = SlackMessage.objects.filter(channel__isnull=True) | ||
|
||
total_messages = slack_messages.count() | ||
if total_messages == 0: | ||
logger.info("No orphaned SlackMessages need to be dropped.") | ||
return | ||
|
||
logger.info(f"Found {total_messages} orphaned SlackMessages to drop.") | ||
|
||
slack_messages.delete() | ||
|
||
logger.info("Finished migration to drop orphaned SlackMessages.") | ||
|
||
|
||
def fill_in_missing_slack_team_identity_values(apps, schema_editor): | ||
""" | ||
This migration fills in the missing `slack_team_identity` field for SlackMessage records that were | ||
created before the field was added. This field is required for the SlackMessage model to be valid, and it is | ||
necessary for the SlackMessage model to be associated with a SlackChannel model. | ||
""" | ||
SlackMessage = apps.get_model("slack", "SlackMessage") | ||
SlackChannel = apps.get_model("slack", "SlackChannel") | ||
|
||
logger.info("Starting migration to fill in missing SlackMessage.slack_team_identity values") | ||
|
||
if schema_editor.connection.vendor == "mysql": | ||
# Use raw SQL for MySQL | ||
with schema_editor.connection.cursor() as cursor: | ||
# Update SlackMessages by joining with SlackChannel | ||
sql_update = """ | ||
UPDATE slack_slackmessage sm | ||
JOIN slack_slackchannel sc ON sm.channel_id = sc.id | ||
SET sm.slack_team_identity = sc.slack_team_identity_id | ||
WHERE sm.slack_team_identity IS NULL | ||
AND sm.channel_id IS NOT NULL | ||
AND sc.slack_team_identity_id IS NOT NULL; | ||
""" | ||
cursor.execute(sql_update) | ||
updated_rows = cursor.rowcount # Number of rows updated | ||
|
||
logger.info(f"Updated {updated_rows} SlackMessages with slack_team_identity from slack_channel.") | ||
|
||
# Count remaining messages that couldn't be updated | ||
cursor.execute(""" | ||
SELECT COUNT(*) | ||
FROM slack_slackmessage sm | ||
LEFT JOIN slack_slackchannel sc ON sm.channel_id = sc.id | ||
WHERE sm.slack_team_identity IS NULL | ||
AND (sm.channel_id IS NULL OR sc.slack_team_identity_id IS NULL); | ||
""") | ||
remaining_count = cursor.fetchone()[0] | ||
|
||
if remaining_count > 0: | ||
logger.warning( | ||
f"{remaining_count} SlackMessages could not be updated because slack_channel or slack_channel.slack_team_identity is missing." | ||
) | ||
else: | ||
# Use Django ORM for other databases | ||
slack_messages = SlackMessage.objects.filter(_slack_team_identity__isnull=True) | ||
|
||
total_messages = slack_messages.count() | ||
if total_messages == 0: | ||
logger.info("No missing SlackMessage.slack_team_identity values") | ||
return | ||
|
||
logger.info(f"Found {total_messages} SlackMessages which have missing slack_team_identity values.") | ||
|
||
# Subquery to get slack_team_identity from SlackChannel | ||
channel_team_identity_subquery = SlackChannel.objects.filter( | ||
pk=OuterRef('channel_id') | ||
).values('slack_team_identity_id')[:1] | ||
|
||
# Update from slack_channel | ||
updated_count = slack_messages.filter( | ||
channel__isnull=False, | ||
channel__slack_team_identity__isnull=False | ||
).update( | ||
_slack_team_identity=Subquery(channel_team_identity_subquery) | ||
) | ||
|
||
logger.info(f"Updated {updated_count} SlackMessages with slack_team_identity from slack_channel.") | ||
|
||
# Check if there are any SlackMessages that couldn't be updated | ||
remaining_messages = SlackMessage.objects.filter(_slack_team_identity__isnull=True) | ||
remaining_count = remaining_messages.count() | ||
|
||
if remaining_count > 0: | ||
logger.warning( | ||
f"{remaining_count} SlackMessages could not be updated because slack_channel or slack_channel.slack_team_identity is missing." | ||
) | ||
|
||
logger.info("Finished migration to fill in missing SlackMessage.slack_team_identity values") | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('slack', '0008_remove_slackmessage_active_update_task_id_state'), | ||
] | ||
|
||
operations = [ | ||
migrations.RunPython(drop_orphaned_slack_messages, migrations.RunPython.noop), | ||
migrations.RunPython(fill_in_missing_slack_team_identity_values, migrations.RunPython.noop), | ||
] |
106 changes: 0 additions & 106 deletions
106
.../migrations/0009_rename__slack_team_identity_slackmessage_slack_team_identity_and_more.py
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.