Complete migration reset

This commit is contained in:
Klaas van Schelven
2024-06-14 10:29:10 +02:00
parent 034c6fecc7
commit 8ad6059722
78 changed files with 238 additions and 1464 deletions

View File

@@ -1,5 +1,4 @@
from django.db import migrations, models
import django.db.models.deletion
import uuid
@@ -8,15 +7,15 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('projects', '0002_project_name_project_sentry_key'),
]
operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('event_id', models.UUIDField(editable=False)),
('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='Bugsink-internal', primary_key=True, serialize=False)),
('server_side_timestamp', models.DateTimeField(db_index=True)),
('event_id', models.UUIDField(editable=False, help_text='As per the sent data')),
('data', models.TextField()),
('timestamp', models.DateTimeField(db_index=True)),
('platform', models.CharField(choices=[('as3', 'As3'), ('c', 'C'), ('cfml', 'Cfml'), ('cocoa', 'Cocoa'), ('csharp', 'Csharp'), ('elixir', 'Elixir'), ('haskell', 'Haskell'), ('go', 'Go'), ('groovy', 'Groovy'), ('java', 'Java'), ('javascript', 'Javascript'), ('native', 'Native'), ('node', 'Node'), ('objc', 'Objc'), ('other', 'Other'), ('perl', 'Perl'), ('php', 'Php'), ('python', 'Python'), ('ruby', 'Ruby')], max_length=64)),
@@ -29,10 +28,15 @@ class Migration(migrations.Migration):
('environment', models.CharField(blank=True, default='', max_length=64)),
('sdk_name', models.CharField(blank=True, default='', max_length=255)),
('sdk_version', models.CharField(blank=True, default='', max_length=255)),
('project', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project')),
('has_exception', models.BooleanField()),
('has_logentry', models.BooleanField()),
('debug_info', models.CharField(blank=True, default='', max_length=255)),
('calculated_type', models.CharField(blank=True, default='', max_length=255)),
('calculated_value', models.CharField(blank=True, default='', max_length=255)),
('last_frame_filename', models.CharField(blank=True, default='', max_length=255)),
('last_frame_module', models.CharField(blank=True, default='', max_length=255)),
('last_frame_function', models.CharField(blank=True, default='', max_length=255)),
('ingest_order', models.PositiveIntegerField()),
],
options={
'unique_together': {('project', 'event_id')},
},
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='event',
name='debug_info',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View File

@@ -4,8 +4,11 @@ import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('events', '0004_event_server_side_timestamp'),
('issues', '0001_initial'),
('events', '0001_initial'),
]
operations = [

View File

@@ -1,23 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0002_event_debug_info'),
]
operations = [
migrations.AddField(
model_name='event',
name='has_exception',
field=models.BooleanField(default=False),
preserve_default=False,
),
migrations.AddField(
model_name='event',
name='has_logentry',
field=models.BooleanField(default=False),
preserve_default=False,
),
]

View File

@@ -4,15 +4,21 @@ import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('projects', '0001_initial'),
('issues', '0001_initial'),
('events', '0002_initial'),
]
operations = [
migrations.AddField(
model_name='issue',
model_name='event',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project'),
),
migrations.AlterUniqueTogether(
name='event',
unique_together={('project', 'event_id'), ('issue', 'ingest_order')},
),
]

View File

@@ -1,18 +0,0 @@
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('events', '0003_event_has_exception_event_has_logentry'),
]
operations = [
migrations.AddField(
model_name='event',
name='server_side_timestamp',
field=models.DateTimeField(db_index=True, default=django.utils.timezone.now),
preserve_default=False,
),
]

View File

@@ -1,25 +0,0 @@
from django.db import migrations
def set_event_issue(apps, schema_editor):
# this was never actually run successfully (the code that ran was a different version), but it's not needed anymore
# anyway :-) kept for laughs and giggles
Issue = apps.get_model('issues', 'Issue')
for issue in Issue.objects.all():
for event in issue.events.all():
event.issue = issue
event.save()
class Migration(migrations.Migration):
dependencies = [
('events', '0005_event_issue'),
('issues', '0006_issue_is_muted_and_more'),
]
operations = [
migrations.RunPython(set_event_issue),
]

View File

@@ -1,18 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('issues', '0007_remove_issue_events'),
('events', '0006_auto_20240105_1954'),
]
operations = [
migrations.AlterField(
model_name='event',
name='issue',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='events', to='issues.issue'),
),
]

View File

@@ -1,18 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('issues', '0007_remove_issue_events'),
('events', '0007_alter_event_issue'),
]
operations = [
migrations.AlterField(
model_name='event',
name='issue',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='issues.issue'),
),
]

View File

@@ -1,18 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('ingest', '0003_decompressedevent_debug_info'),
('events', '0008_alter_event_issue'),
]
operations = [
migrations.AddField(
model_name='event',
name='ingested_event',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='ingest.decompressedevent'),
),
]

View File

@@ -1,24 +0,0 @@
# Generated by Django 4.2.11 on 2024-03-30 20:00
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('events', '0009_event_ingested_event'),
]
operations = [
migrations.AlterField(
model_name='event',
name='event_id',
field=models.UUIDField(editable=False, help_text='As per the sent data'),
),
migrations.AlterField(
model_name='event',
name='id',
field=models.UUIDField(default=uuid.uuid4, editable=False, help_text='Bugsink-internal', primary_key=True, serialize=False),
),
]

View File

@@ -1,23 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-08 13:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0010_alter_event_event_id_alter_event_id'),
]
operations = [
migrations.AddField(
model_name='event',
name='calculated_type',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='event',
name='calculated_value',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View File

@@ -1,35 +0,0 @@
import json
from django.db import migrations
from issues.utils import get_type_and_value_for_data
def fill_calculated_data(apps, schema_editor):
# same caveats on lack of code copy-pasting, as well as the reasons these caveats probably don't matter, apply as in
# the previous data-migration.
Event = apps.get_model('events', 'Event')
Issue = apps.get_model('issues', 'Issue')
for event in Event.objects.all():
event_data = json.loads(event.data)
event.calculated_type, event.calculated_value = get_type_and_value_for_data(event_data)
event.save()
# this is for Issues, which is not in the same app, but who cares
for issue in Issue.objects.all():
event_data = json.loads(issue.event_set.first().data)
issue.calculated_type, issue.calculated_value = get_type_and_value_for_data(event_data)
issue.save()
class Migration(migrations.Migration):
dependencies = [
('events', '0011_event_calculated_type_event_calculated_value'),
]
operations = [
migrations.RunPython(fill_calculated_data, migrations.RunPython.noop),
]

View File

@@ -1,19 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-08 19:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0012_events_calculated_data'),
]
operations = [
migrations.AddField(
model_name='event',
name='ingest_order',
field=models.IntegerField(default=666),
preserve_default=False,
),
]

View File

@@ -1,24 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-08 19:22
from django.db import migrations
def fill_ingest_order(apps, schema_editor):
Issue = apps.get_model('issues', 'Issue')
Event = apps.get_model('events', 'Event')
for issue in Issue.objects.all():
for i, event in enumerate(Event.objects.filter(issue=issue).order_by('server_side_timestamp', 'timestamp')):
event.ingest_order = i + 1
event.save()
class Migration(migrations.Migration):
dependencies = [
('events', '0013_event_ingest_order'),
]
operations = [
migrations.RunPython(fill_ingest_order),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0014_fill_ingest_order'),
]
operations = [
migrations.AlterField(
model_name='event',
name='ingest_order',
field=models.PositiveIntegerField(),
),
]

View File

@@ -1,28 +0,0 @@
from django.db import migrations
from django.db import models
def check_unique_together(apps, schema_editor):
# manual check, allows for a pdb when this migration fails
Event = apps.get_model('events', 'Event')
for index in [('project', 'event_id'), ('issue', 'ingest_order')]:
values = Event.objects.values(*index).annotate(count=models.Count('id')).filter(count__gt=1)
if values:
raise ValueError(f"Duplicate event_id values found: {values}")
class Migration(migrations.Migration):
dependencies = [
('projects', '0008_set_project_slugs'),
('events', '0015_alter_event_ingest_order'),
]
operations = [
migrations.RunPython(check_unique_together),
migrations.AlterUniqueTogether(
name='event',
unique_together={('project', 'event_id'), ('issue', 'ingest_order')},
),
]

View File

@@ -1,26 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0016_alter_event_unique_together'),
]
operations = [
migrations.AddField(
model_name='event',
name='last_frame_filename',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='event',
name='last_frame_function',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='event',
name='last_frame_module',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View File

@@ -1,39 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-09 19:54
import json
from django.db import migrations
from issues.utils import get_denormalized_fields_for_data
def fill_denormalized_fields(apps, schema_editor):
# This function does both events and issues; we don't care about the fact that this is "formally incorrect" as long
# as we can keep developing for now.
Event = apps.get_model('events', 'Event')
for event in Event.objects.all():
denormalized_fields = get_denormalized_fields_for_data(json.loads(event.data))
for k, v in denormalized_fields.items():
setattr(event, k, v)
event.save()
# inefficient, because we do each issue multiple times, but who cares, this is just to have something "for now"
issue = event.issue
for k, v in denormalized_fields.items():
setattr(issue, k, v)
issue.save()
class Migration(migrations.Migration):
dependencies = [
('events', '0017_event_last_frame_filename_event_last_frame_function_and_more'),
('ingest', '0003_decompressedevent_debug_info'),
('issues', '0021_issue_last_frame_filename_issue_last_frame_function_and_more'),
('projects', '0008_set_project_slugs'),
('releases', '0003_alter_release_version'),
]
operations = [
migrations.RunPython(fill_denormalized_fields),
]

View File

@@ -1,17 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-26 08:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0018_fill_denormalized_fields'),
]
operations = [
migrations.RemoveField(
model_name='event',
name='ingested_event',
),
]

View File

@@ -1,24 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
('projects', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='DecompressedEvent',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('data', models.TextField()),
('timestamp', models.DateTimeField(auto_now_add=True, help_text='Server-side timestamp')),
('project', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project')),
],
),
]

View File

@@ -69,11 +69,22 @@ class Migration(migrations.Migration):
atomic = False
dependencies = [
('events', '0018_fill_denormalized_fields'),
('ingest', '0003_decompressedevent_debug_info'),
('issues', '0022_turningpoint'),
('projects', '0008_set_project_slugs'),
('releases', '0003_alter_release_version'),
]
# strictly speaking, running this migration before the others is not necessary, but it seems like the right thing to
# first choose the journaling mode and then create the tables.
run_before = [
('admin', '0001_initial'),
('auth', '0001_initial'),
('contenttypes', '0001_initial'),
('sessions', '0001_initial'),
('events', '0001_initial'),
('issues', '0001_initial'),
('projects', '0001_initial'),
('releases', '0001_initial'),
('teams', '0001_initial'),
('users', '0001_initial'),
]
operations = [

View File

@@ -1,17 +0,0 @@
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('ingest', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='decompressedevent',
name='timestamp',
field=models.DateTimeField(default=django.utils.timezone.now, help_text='Server-side timestamp'),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ingest', '0002_alter_decompressedevent_timestamp'),
]
operations = [
migrations.AddField(
model_name='decompressedevent',
name='debug_info',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View File

@@ -1,17 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-26 08:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0019_remove_event_ingested_event'),
('ingest', '0004_set_sqlite_wal'),
]
operations = [
migrations.DeleteModel(
name='DecompressedEvent',
),
]

View File

@@ -1,4 +1,5 @@
from django.db import migrations, models
import django.db.models.deletion
import uuid
@@ -7,16 +8,53 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('ingest', '0001_initial'),
('events', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Grouping',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('grouping_key', models.TextField()),
],
),
migrations.CreateModel(
name='Issue',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('hash', models.CharField(max_length=32)),
('events', models.ManyToManyField(to='ingest.decompressedevent')),
('ingest_order', models.PositiveIntegerField()),
('last_seen', models.DateTimeField()),
('first_seen', models.DateTimeField()),
('event_count', models.IntegerField()),
('calculated_type', models.CharField(blank=True, default='', max_length=255)),
('calculated_value', models.CharField(blank=True, default='', max_length=255)),
('transaction', models.CharField(blank=True, default='', max_length=200)),
('last_frame_filename', models.CharField(blank=True, default='', max_length=255)),
('last_frame_module', models.CharField(blank=True, default='', max_length=255)),
('last_frame_function', models.CharField(blank=True, default='', max_length=255)),
('is_resolved', models.BooleanField(default=False)),
('is_resolved_by_next_release', models.BooleanField(default=False)),
('fixed_at', models.TextField(blank=True, default='')),
('events_at', models.TextField(blank=True, default='')),
('is_muted', models.BooleanField(default=False)),
('unmute_on_volume_based_conditions', models.TextField(default='[]')),
('unmute_after', models.DateTimeField(blank=True, null=True)),
],
),
migrations.CreateModel(
name='TurningPoint',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField()),
('kind', models.IntegerField(choices=[(1, 'First seen'), (2, 'Resolved'), (3, 'Muted'), (4, 'Marked as regressed'), (5, 'Unmuted'), (10, 'Release info added'), (100, 'Manual annotation')])),
('metadata', models.TextField(default='{}')),
('comment', models.TextField(blank=True, default='')),
('issue', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='issues.issue')),
('triggering_event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.event')),
],
options={
'ordering': ['-timestamp'],
},
),
]

View File

@@ -0,0 +1,53 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('issues', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='turningpoint',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='issue',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project'),
),
migrations.AddField(
model_name='grouping',
name='issue',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='issues.issue'),
),
migrations.AddField(
model_name='grouping',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project'),
),
migrations.AddIndex(
model_name='turningpoint',
index=models.Index(fields=['timestamp'], name='issues_turn_timesta_eaa375_idx'),
),
migrations.AddIndex(
model_name='issue',
index=models.Index(fields=['first_seen'], name='issues_issu_first_s_9fb0f9_idx'),
),
migrations.AddIndex(
model_name='issue',
index=models.Index(fields=['last_seen'], name='issues_issu_last_se_400a05_idx'),
),
migrations.AlterUniqueTogether(
name='issue',
unique_together={('project', 'ingest_order')},
),
]

View File

@@ -1,17 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
('issues', '0002_issue_project'),
]
operations = [
migrations.AlterField(
model_name='issue',
name='events',
field=models.ManyToManyField(to='events.event'),
),
]

View File

@@ -1,26 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0003_alter_issue_events'),
]
operations = [
migrations.AddField(
model_name='issue',
name='events_at',
field=models.TextField(default='[]'),
),
migrations.AddField(
model_name='issue',
name='fixed_at',
field=models.TextField(default='[]'),
),
migrations.AddField(
model_name='issue',
name='is_resolved',
field=models.BooleanField(default=False),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0004_issue_events_at_issue_fixed_at_issue_is_resolved'),
]
operations = [
migrations.AddField(
model_name='issue',
name='is_resolved_by_next_release',
field=models.BooleanField(default=False),
),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0005_issue_is_resolved_by_next_release'),
]
operations = [
migrations.AddField(
model_name='issue',
name='is_muted',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='issue',
name='unmute_on_volume_based_conditions',
field=models.TextField(default='[]'),
),
]

View File

@@ -1,15 +0,0 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('issues', '0006_issue_is_muted_and_more'),
]
operations = [
migrations.RemoveField(
model_name='issue',
name='events',
),
]

View File

@@ -1,30 +0,0 @@
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('issues', '0007_remove_issue_events'),
]
operations = [
migrations.AddField(
model_name='issue',
name='event_count',
field=models.IntegerField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='issue',
name='first_seen',
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='issue',
name='last_seen',
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
]

View File

@@ -1,19 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0008_issue_event_count_issue_first_seen_issue_last_seen'),
]
operations = [
migrations.AddIndex(
model_name='issue',
index=models.Index(fields=['first_seen'], name='issues_issu_first_s_9fb0f9_idx'),
),
migrations.AddIndex(
model_name='issue',
index=models.Index(fields=['last_seen'], name='issues_issu_last_se_400a05_idx'),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0009_issue_issues_issu_first_s_9fb0f9_idx_and_more'),
]
operations = [
migrations.AddField(
model_name='issue',
name='unmute_after',
field=models.DateTimeField(blank=True, null=True),
),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0010_issue_unmute_after'),
]
operations = [
migrations.AlterField(
model_name='issue',
name='events_at',
field=models.TextField(default=''),
),
migrations.AlterField(
model_name='issue',
name='fixed_at',
field=models.TextField(default=''),
),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations
def become_bracketless(apps, schema_editor):
Issue = apps.get_model('issues', 'Issue')
for issue in Issue.objects.all():
issue.fixed_at = issue.fixed_at[1:-1]
issue.events_at = issue.events_at[1:-1]
issue.save()
class Migration(migrations.Migration):
dependencies = [
('issues', '0011_alter_issue_events_at_alter_issue_fixed_at'),
]
operations = [
migrations.RunPython(become_bracketless)
]

View File

@@ -1,31 +0,0 @@
import json
from django.db import migrations
def parse_bracketless(s):
return json.loads(f"[{s}]")
def serialize_lines(l):
return "".join([e + "\n" for e in l])
def become_line_separated(apps, schema_editor):
Issue = apps.get_model('issues', 'Issue')
for issue in Issue.objects.all():
issue.fixed_at = serialize_lines(parse_bracketless(issue.fixed_at))
issue.events_at = serialize_lines(parse_bracketless(issue.events_at))
issue.save()
class Migration(migrations.Migration):
dependencies = [
('issues', '0012_auto_20240320_0927'),
]
operations = [
migrations.RunPython(become_line_separated),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0013_auto_20240320_1235'),
]
operations = [
migrations.AlterField(
model_name='issue',
name='events_at',
field=models.TextField(blank=True, default=''),
),
migrations.AlterField(
model_name='issue',
name='fixed_at',
field=models.TextField(blank=True, default=''),
),
]

View File

@@ -1,28 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-08 08:59
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0006_alter_projectmembership_unique_together'),
('issues', '0014_alter_issue_events_at_alter_issue_fixed_at'),
]
operations = [
migrations.RemoveField(
model_name='issue',
name='hash',
),
migrations.CreateModel(
name='Grouping',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('grouping_key', models.TextField()),
('issue', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='issues.issue')),
('project', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project')),
],
),
]

View File

@@ -1,36 +0,0 @@
import json
from django.db import migrations
from issues.utils import get_issue_grouper_for_data
def create_grouping_objects(apps, schema_editor):
Issue = apps.get_model('issues', 'Issue')
Grouping = apps.get_model('issues', 'Grouping')
for issue in Issue.objects.all():
# we can do this because we know that there is at least one event, and because the events are already grouped
# per issue (we just need to reconstruct the grouping key as implied by the hash)
some_random_event = issue.event_set.first()
event_data = json.loads(some_random_event.data)
# we have _not_ inlined the code (which is standard good practice when creating datamigrations). Reason: this
# data-migration is just here for my own development process, we don't need it to be perfect.
grouping_key = get_issue_grouper_for_data(event_data)
Grouping.objects.create(
project=issue.project,
issue=issue,
grouping_key=grouping_key,
)
class Migration(migrations.Migration):
dependencies = [
('issues', '0015_remove_issue_hash_grouping'),
]
operations = [
migrations.RunPython(create_grouping_objects),
]

View File

@@ -1,23 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-08 13:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0016_create_grouping_objects'),
]
operations = [
migrations.AddField(
model_name='issue',
name='calculated_type',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='issue',
name='calculated_value',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View File

@@ -1,17 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0017_issue_calculated_type_issue_calculated_value'),
]
operations = [
migrations.AddField(
model_name='issue',
name='ingest_order',
field=models.PositiveIntegerField(default=123),
preserve_default=False,
),
]

View File

@@ -1,24 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-09 08:37
from django.db import migrations
def fill_ingest_order(apps, schema_editor):
Issue = apps.get_model('issues', 'Issue')
Project = apps.get_model('projects', 'Project')
for project in Project.objects.all():
for i, issue in enumerate(Issue.objects.filter(project=project).order_by('first_seen')):
issue.ingest_order = i + 1
issue.save()
class Migration(migrations.Migration):
dependencies = [
('issues', '0018_issue_ingest_order'),
]
operations = [
migrations.RunPython(fill_ingest_order),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0008_set_project_slugs'),
('issues', '0019_set_ingest_order'),
]
operations = [
migrations.AlterUniqueTogether(
name='issue',
unique_together={('project', 'ingest_order')},
),
]

View File

@@ -1,31 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0020_alter_issue_unique_together'),
]
operations = [
migrations.AddField(
model_name='issue',
name='last_frame_filename',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='issue',
name='last_frame_function',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='issue',
name='last_frame_module',
field=models.CharField(blank=True, default='', max_length=255),
),
migrations.AddField(
model_name='issue',
name='transaction',
field=models.CharField(blank=True, default='', max_length=200),
),
]

View File

@@ -1,30 +0,0 @@
# Generated by Django 4.2.11 on 2024-04-12 08:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('events', '0018_fill_denormalized_fields'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('issues', '0021_issue_last_frame_filename_issue_last_frame_function_and_more'),
]
operations = [
migrations.CreateModel(
name='TurningPoint',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField()),
('kind', models.IntegerField(choices=[(1, 'First seen'), (2, 'Resolved'), (3, 'Muted'), (4, 'Regressed'), (5, 'Unmuted'), (100, 'Manual annotation')])),
('metadata', models.TextField(default='{}')),
('comment', models.TextField(blank=True, default='')),
('issue', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='issues.issue')),
('triggering_event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.event')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -1,26 +0,0 @@
# Generated by Django 4.2.11 on 2024-05-17 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('issues', '0022_turningpoint'),
]
operations = [
migrations.AlterModelOptions(
name='turningpoint',
options={'ordering': ['-timestamp']},
),
migrations.AlterField(
model_name='turningpoint',
name='kind',
field=models.IntegerField(choices=[(1, 'First seen'), (2, 'Resolved'), (3, 'Muted'), (4, 'Marked as regressed'), (5, 'Unmuted'), (10, 'Release info added'), (100, 'Manual annotation')]),
),
migrations.AddIndex(
model_name='turningpoint',
index=models.Index(fields=['timestamp'], name='issues_turn_timesta_eaa375_idx'),
),
]

View File

@@ -1,4 +1,6 @@
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
@@ -13,6 +15,24 @@ class Migration(migrations.Migration):
name='Project',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('slug', models.SlugField(unique=True)),
('sentry_key', models.UUIDField(default=uuid.uuid4, editable=False)),
('has_releases', models.BooleanField(default=False, editable=False)),
('alert_on_new_issue', models.BooleanField(default=True)),
('alert_on_regression', models.BooleanField(default=True)),
('alert_on_unmute', models.BooleanField(default=True)),
('visibility', models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Team Members')], default=99)),
],
),
migrations.CreateModel(
name='ProjectMembership',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('send_email_alerts', models.BooleanField(default=None, null=True)),
('role', models.IntegerField(choices=[(0, 'Member'), (1, 'Admin')], default=0)),
('accepted', models.BooleanField(default=False)),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='projects.project')),
],
),
]

View File

@@ -0,0 +1,36 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('teams', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='projectmembership',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='team',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='teams.team'),
),
migrations.AddField(
model_name='project',
name='users',
field=models.ManyToManyField(blank=True, through='projects.ProjectMembership', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='projectmembership',
unique_together={('project', 'user')},
),
]

View File

@@ -1,23 +0,0 @@
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('projects', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='project',
name='name',
field=models.CharField(default='asdf', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='project',
name='sentry_key',
field=models.UUIDField(default=uuid.uuid4, editable=False),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0002_project_name_project_sentry_key'),
]
operations = [
migrations.AddField(
model_name='project',
name='has_releases',
field=models.BooleanField(default=False, editable=False),
),
]

View File

@@ -1,26 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0003_project_has_releases'),
]
operations = [
migrations.AddField(
model_name='project',
name='alert_on_new_issue',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='project',
name='alert_on_regression',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='project',
name='alert_on_unmute',
field=models.BooleanField(default=True),
),
]

View File

@@ -1,28 +0,0 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0004_project_alert_on_new_issue_and_more'),
]
operations = [
migrations.CreateModel(
name='ProjectMembership',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('send_email_alerts', models.BooleanField(default=True)),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='projects.project')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='project',
name='users',
field=models.ManyToManyField(blank=True, through='projects.ProjectMembership', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -1,17 +0,0 @@
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0005_projectmembership_project_users'),
]
operations = [
migrations.AlterUniqueTogether(
name='projectmembership',
unique_together={('project', 'user')},
),
]

View File

@@ -1,17 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0006_alter_projectmembership_unique_together'),
]
operations = [
migrations.AddField(
model_name='project',
name='slug',
field=models.SlugField(default='notset'),
preserve_default=False,
),
]

View File

@@ -1,20 +0,0 @@
from django.db import migrations
from django.utils.text import slugify
def set_project_slugs(apps, schema_editor):
Project = apps.get_model('projects', 'Project')
for project in Project.objects.all():
project.slug = slugify(project.name)
project.save()
class Migration(migrations.Migration):
dependencies = [
('projects', '0007_project_slug'),
]
operations = [
migrations.RunPython(set_project_slugs),
]

View File

@@ -1,18 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('teams', '0002_create_single_team'),
('projects', '0008_set_project_slugs'),
]
operations = [
migrations.AddField(
model_name='project',
name='team',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='teams.team'),
),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations
def set_single_team(apps, schema_editor):
Team = apps.get_model('teams', 'Team')
Project = apps.get_model('projects', 'Project')
team = Team.objects.all().first() # as created in 0002_create_single_team
Project.objects.update(team=team)
class Migration(migrations.Migration):
dependencies = [
('projects', '0009_project_team'),
('teams', '0002_create_single_team'),
]
operations = [
migrations.RunPython(set_single_team),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0010_set_single_team'),
]
operations = [
migrations.AddField(
model_name='projectmembership',
name='accepted',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='projectmembership',
name='role',
field=models.IntegerField(choices=[(0, 'Member'), (1, 'Admin')], default=0),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0011_projectmembership_accepted_projectmembership_role'),
]
operations = [
migrations.AlterField(
model_name='projectmembership',
name='send_email_alerts',
field=models.BooleanField(default=None, null=True),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.13 on 2024-06-06 12:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0012_alter_projectmembership_send_email_alerts'),
]
operations = [
migrations.AddField(
model_name='project',
name='visibility',
field=models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Hidden')], default=99),
),
]

View File

@@ -1,21 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0013_project_visibility'),
]
operations = [
migrations.AlterField(
model_name='project',
name='slug',
field=models.SlugField(unique=True),
),
migrations.AlterField(
model_name='project',
name='visibility',
field=models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Team Members')], default=99),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0014_alter_project_slug_alter_project_visibility'),
]
operations = [
migrations.AlterField(
model_name='project',
name='name',
field=models.CharField(max_length=255, unique=True),
),
]

View File

@@ -9,7 +9,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('projects', '0002_project_name_project_sentry_key'),
('projects', '0001_initial'),
]
operations = [
@@ -17,10 +17,11 @@ class Migration(migrations.Migration):
name='Release',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('version', models.CharField(max_length=255)),
('version', models.CharField(max_length=250)),
('date_released', models.DateTimeField(default=django.utils.timezone.now)),
('is_semver', models.BooleanField()),
('sort_epoch', models.IntegerField()),
('semver', models.CharField(editable=False, max_length=255)),
('is_semver', models.BooleanField(editable=False)),
('sort_epoch', models.IntegerField(editable=False)),
('project', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project')),
],
options={

View File

@@ -1,27 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('releases', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='release',
name='semver',
field=models.CharField(default='', editable=False, max_length=255),
preserve_default=False,
),
migrations.AlterField(
model_name='release',
name='is_semver',
field=models.BooleanField(editable=False),
),
migrations.AlterField(
model_name='release',
name='sort_epoch',
field=models.IntegerField(editable=False),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('releases', '0002_release_semver_alter_release_is_semver_and_more'),
]
operations = [
migrations.AlterField(
model_name='release',
name='version',
field=models.CharField(max_length=250),
),
]

View File

@@ -1,4 +1,3 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
@@ -9,7 +8,6 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
@@ -17,20 +15,19 @@ class Migration(migrations.Migration):
name='Team',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=255)),
('name', models.CharField(max_length=255, unique=True)),
('slug', models.SlugField()),
('visibility', models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Hidden')], default=10)),
],
),
migrations.CreateModel(
name='TeamMembership',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('send_email_alerts', models.BooleanField(blank=True, default=None, null=True)),
('role', models.IntegerField(choices=[(0, 'Member'), (1, 'Admin')], default=0)),
('accepted', models.BooleanField(default=False)),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teams.team')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('team', 'user')},
},
),
]

View File

@@ -1,25 +0,0 @@
from django.db import migrations
def create_single_team(apps, schema_editor):
# if needed (for existing projects); this should not be preserved when we squash/restart migrations
Project = apps.get_model('projects', 'Project')
Team = apps.get_model('teams', 'Team')
if Project.objects.count() == 0:
return
Team.objects.create(name='Single Team', slug='single-team')
class Migration(migrations.Migration):
dependencies = [
('teams', '0001_initial'),
('projects', '0008_set_project_slugs'),
]
operations = [
migrations.RunPython(create_single_team),
]

View File

@@ -0,0 +1,25 @@
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('teams', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='teammembership',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='teammembership',
unique_together={('team', 'user')},
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teams', '0002_create_single_team'),
]
operations = [
migrations.AddField(
model_name='team',
name='visibility',
field=models.IntegerField(choices=[(0, 'Public'), (1, 'Visible'), (2, 'Hidden')], default=0),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teams', '0003_team_visibility'),
]
operations = [
migrations.AddField(
model_name='teammembership',
name='accepted',
field=models.BooleanField(default=False),
),
]

View File

@@ -1,16 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teams', '0004_teammembership_accepted'),
]
operations = [
migrations.AddField(
model_name='teammembership',
name='send_email_alerts',
field=models.BooleanField(blank=True, default=True, null=True),
),
]

View File

@@ -1,26 +0,0 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teams', '0005_teammembership_send_email_alerts'),
]
operations = [
migrations.AlterField(
model_name='team',
name='name',
field=models.CharField(max_length=255, unique=True),
),
migrations.AlterField(
model_name='team',
name='visibility',
field=models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Hidden')], default=1),
),
migrations.AlterField(
model_name='teammembership',
name='send_email_alerts',
field=models.BooleanField(blank=True, default=None, null=True),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.13 on 2024-06-06 12:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('teams', '0006_alter_team_name_alter_team_visibility_and_more'),
]
operations = [
migrations.AlterField(
model_name='team',
name='visibility',
field=models.IntegerField(choices=[(1, 'Joinable'), (10, 'Visible'), (99, 'Hidden')], default=10),
),
]

View File

@@ -1,17 +1,14 @@
# Generated by Django 4.2.13 on 2024-05-29 08:00
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import secrets
class Migration(migrations.Migration):
# Since this was introduced later, it "shouldn't" work in theory, but it appears to work in practice, as long as you
# manually fake it using:
# INSERT INTO django_migrations (app, name, applied) VALUES ('users', '0001_initial', '2023-11-05 16:18:04.716257');
initial = True
dependencies = [
@@ -33,6 +30,7 @@ class Migration(migrations.Migration):
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('send_email_alerts', models.BooleanField(blank=True, default=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
@@ -43,4 +41,14 @@ class Migration(migrations.Migration):
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='EmailVerification',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('token', models.CharField(default=secrets.token_urlsafe, max_length=64)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -1,26 +0,0 @@
# Generated by Django 4.2.13 on 2024-05-29 15:00
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import secrets
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='EmailVerification',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('token', models.CharField(default=secrets.token_urlsafe, max_length=64)),
('created_at', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.13 on 2024-06-12 14:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0002_emailverification'),
]
operations = [
migrations.AddField(
model_name='user',
name='send_email_alerts',
field=models.BooleanField(blank=True, default=True),
),
]