agendas: change Event id field to have a BigAutoField (#74008) #33

Merged
lguerin merged 1 commits from wip/74008-bigautofield into main 2023-02-03 11:17:54 +01:00
4 changed files with 52 additions and 2 deletions

View File

@ -0,0 +1,42 @@
import os
from django.db import migrations, models
sql_forwards_bigint = """
ALTER SEQUENCE "agendas_event_id_seq" as bigint MAXVALUE 9223372036854775807;
ALTER TABLE "agendas_event" ALTER COLUMN "id" TYPE bigint USING "id"::bigint, ALTER COLUMN "primary_event_id" TYPE bigint USING "primary_event_id"::bigint;
ALTER TABLE "agendas_booking" ALTER COLUMN "event_id" TYPE bigint USING "event_id"::bigint;
lguerin marked this conversation as resolved Outdated

Un seul alter par table stp :)

Un seul alter par table stp :)
ALTER TABLE "agendas_event_resources" ALTER COLUMN "event_id" TYPE bigint USING "event_id"::bigint;
ALTER TABLE "agendas_eventcancellationreport" ALTER COLUMN "event_id" TYPE bigint USING "event_id"::bigint;
ALTER TABLE "agendas_recurrenceexceptionsreport_events" ALTER COLUMN "event_id" TYPE bigint USING "event_id"::bigint;
"""

laisser django faire ne suffit pas:

SET CONSTRAINTS "agendas_event_primary_event_id_539e724e_fk_agendas_event_id" IMMEDIATE; ALTER TABLE "agendas_event" DROP CONSTRAINT "agendas_event_primary_event_id_539e724e_fk_agendas_event_id"
ALTER TABLE "agendas_event" ALTER COLUMN "id" TYPE bigint USING "id"::bigint
NOTICE:  DROP cascade sur valeur par défaut pour  colonne id de table agendas_event
DROP SEQUENCE IF EXISTS "agendas_event_id_seq" CASCADE
CREATE SEQUENCE "agendas_event_id_seq"
ALTER TABLE "agendas_event" ALTER COLUMN "id" SET DEFAULT nextval('"agendas_event_id_seq"')
SELECT setval('"agendas_event_id_seq"', MAX("id")) FROM "agendas_event"
ALTER TABLE "agendas_event" ALTER COLUMN "primary_event_id" TYPE bigint USING "primary_event_id"::bigint
ALTER TABLE "agendas_event" ADD CONSTRAINT "agendas_event_primary_event_id_539e724e_fk" FOREIGN KEY ("primary_event_id") REFERENCES "agendas_event" ("id") DEFERRABLE INITIALLY DEFERRED

Il drop la séquence (gloups), et ne traite que le model Event, pas les FK des autres models.

laisser django faire ne suffit pas: ``` SET CONSTRAINTS "agendas_event_primary_event_id_539e724e_fk_agendas_event_id" IMMEDIATE; ALTER TABLE "agendas_event" DROP CONSTRAINT "agendas_event_primary_event_id_539e724e_fk_agendas_event_id" ALTER TABLE "agendas_event" ALTER COLUMN "id" TYPE bigint USING "id"::bigint NOTICE: DROP cascade sur valeur par défaut pour colonne id de table agendas_event DROP SEQUENCE IF EXISTS "agendas_event_id_seq" CASCADE CREATE SEQUENCE "agendas_event_id_seq" ALTER TABLE "agendas_event" ALTER COLUMN "id" SET DEFAULT nextval('"agendas_event_id_seq"') SELECT setval('"agendas_event_id_seq"', MAX("id")) FROM "agendas_event" ALTER TABLE "agendas_event" ALTER COLUMN "primary_event_id" TYPE bigint USING "primary_event_id"::bigint ALTER TABLE "agendas_event" ADD CONSTRAINT "agendas_event_primary_event_id_539e724e_fk" FOREIGN KEY ("primary_event_id") REFERENCES "agendas_event" ("id") DEFERRABLE INITIALLY DEFERRED ``` Il drop la séquence (gloups), et ne traite que le model Event, pas les FK des autres models.
with open(
os.path.join(
os.path.dirname(os.path.realpath(__file__)), '..', 'sql', 'event_booked_places_and_full_triggers.sql'
)
) as sql_file:
sql_forwards_triggers = sql_file.read()
class Migration(migrations.Migration):
dependencies = [
('agendas', '0145_user_phone_number'),
]
operations = [
migrations.RunSQL(
sql=sql_forwards_bigint,
reverse_sql=migrations.RunSQL.noop,
state_operations=[
migrations.AlterField(
model_name='event',
name='id',
field=models.BigAutoField(primary_key=True, serialize=False),
),
],
),
migrations.RunSQL(sql=sql_forwards_triggers, reverse_sql=migrations.RunSQL.noop),
]

View File

@ -1434,6 +1434,7 @@ class MeetingType(models.Model):
class Event(models.Model):
id = models.BigAutoField(primary_key=True)
INTERVAL_CHOICES = [
(1, _('Every week')),
(2, _('Every two weeks')),

View File

@ -35,7 +35,7 @@ $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION update_event_places_fields() RETURNS TRIGGER AS $$
DECLARE
e_id integer;
e_id bigint;
BEGIN
IF (TG_OP = 'DELETE') THEN
e_id = OLD.event_id;

View File

@ -8,7 +8,7 @@ import requests
from django.contrib.auth.models import Group, User
from django.core.files.base import ContentFile
from django.core.management import call_command
from django.db import IntegrityError, transaction
from django.db import IntegrityError, connection, transaction
from django.db.models import Q
from django.test import override_settings
from django.utils.timezone import localtime, make_aware, now
@ -2625,6 +2625,13 @@ def test_recurring_events_display(freezer):
def test_event_triggered_fields():
# alter event pk sequence to have a bigint
with connection.cursor() as cursor:
cursor.execute("SELECT nextval('agendas_event_id_seq')")
row = cursor.fetchone()
if row[0] < 2**31:
cursor.execute("ALTER SEQUENCE agendas_event_id_seq RESTART WITH %s;" % 2**31)
Review

pour tester au moins une fois, mais pas forcément sur toutes les FK, que ça passe sur un bigint
mais on peut virer ça maintenant que jenkins est passé au moins une fois

pour tester au moins une fois, mais pas forcément sur toutes les FK, que ça passe sur un bigint mais on peut virer ça maintenant que jenkins est passé au moins une fois
Review

pour tester au moins une fois, mais pas forcément sur toutes les FK, que ça passe sur un bigint
mais on peut virer ça maintenant que jenkins est passé au moins une fois

pour tester au moins une fois, mais pas forcément sur toutes les FK, que ça passe sur un bigint mais on peut virer ça maintenant que jenkins est passé au moins une fois
agenda = Agenda.objects.create(label='Agenda', kind='events')
event = Event.objects.create(
agenda=agenda, start_datetime=now() + datetime.timedelta(days=10), places=10, label='Event'