Skip to content

Commit af9e464

Browse files
committed
feat: Migration for Elections and Officers
- closes #71: Added unique constraint Officer Term - Changed TIMESTAMP to DATETIME on Elections table
1 parent 14cef35 commit af9e464

File tree

5 files changed

+64
-11
lines changed

5 files changed

+64
-11
lines changed

src/alembic/env.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import blog.tables
1010
import database
1111
import elections.tables
12+
import nominees.tables
1213
import officers.tables
14+
import registrations.tables
1315
from alembic import context
1416

1517
# this is the Alembic Config object, which provides
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""add_unique_constraint_officer_term_71
2+
3+
Revision ID: 6b58a293a7df
4+
Revises: 243190df5588
5+
Create Date: 2025-09-28 17:13:51.024959
6+
7+
"""
8+
from collections.abc import Sequence
9+
10+
import sqlalchemy as sa
11+
12+
from alembic import op
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = "6b58a293a7df"
16+
down_revision: str | None = "243190df5588"
17+
branch_labels: str | Sequence[str] | None = None
18+
depends_on: str | Sequence[str] | None = None
19+
20+
21+
def upgrade() -> None:
22+
# ### commands auto generated by Alembic - please adjust! ###
23+
op.alter_column("election", "type",
24+
existing_type=sa.VARCHAR(length=64),
25+
nullable=False)
26+
op.alter_column("officer_term", "start_date",
27+
existing_type=sa.DATE(),
28+
type_=sa.DateTime(),
29+
existing_nullable=False)
30+
op.alter_column("officer_term", "end_date",
31+
existing_type=sa.DATE(),
32+
type_=sa.DateTime(),
33+
existing_nullable=True)
34+
op.create_unique_constraint(op.f("uq_officer_term_computing_id"), "officer_term", ["computing_id", "position", "start_date"])
35+
# ### end Alembic commands ###
36+
37+
38+
def downgrade() -> None:
39+
# ### commands auto generated by Alembic - please adjust! ###
40+
op.drop_constraint(op.f("uq_officer_term_computing_id"), "officer_term", type_="unique")
41+
op.alter_column("officer_term", "end_date",
42+
existing_type=sa.DateTime(),
43+
type_=sa.DATE(),
44+
existing_nullable=True)
45+
op.alter_column("officer_term", "start_date",
46+
existing_type=sa.DateTime(),
47+
type_=sa.DATE(),
48+
existing_nullable=False)
49+
op.alter_column("election", "type",
50+
existing_type=sa.VARCHAR(length=64),
51+
nullable=True)
52+
# ### end Alembic commands ###

src/elections/tables.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ class Election(Base):
2525
slug: Mapped[str] = mapped_column(String(MAX_ELECTION_SLUG), primary_key=True)
2626
name: Mapped[str] = mapped_column(String(MAX_ELECTION_NAME), nullable=False)
2727
type: Mapped[ElectionTypeEnum] = mapped_column(String(64), default=ElectionTypeEnum.GENERAL)
28-
datetime_start_nominations: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
29-
datetime_start_voting: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
30-
datetime_end_voting: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
28+
datetime_start_nominations: Mapped[datetime] = mapped_column(DateTime, nullable=False)
29+
datetime_start_voting: Mapped[datetime] = mapped_column(DateTime, nullable=False)
30+
datetime_end_voting: Mapped[datetime] = mapped_column(DateTime, nullable=False)
3131

3232
# a comma-separated string of positions which must be elements of OfficerPosition
3333
# By giving it the type `StringList`, the database entry will automatically be marshalled to the correct form

src/nominees/tables.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ class NomineeInfo(Base):
1414
__tablename__ = "election_nominee_info"
1515

1616
computing_id: Mapped[str] = mapped_column(String(COMPUTING_ID_LEN), primary_key=True)
17-
full_name: Mapped[str] = mapped_column(String(64), nullable=False)
18-
linked_in: Mapped[str] = mapped_column(String(128))
19-
instagram: Mapped[str] = mapped_column(String(128))
20-
email: Mapped[str] = mapped_column(String(64))
21-
discord_username: Mapped[str] = mapped_column(String(DISCORD_NICKNAME_LEN))
17+
full_name: Mapped[str] = mapped_column(String(64))
18+
linked_in: Mapped[str] = mapped_column(String(128), nullable=True)
19+
instagram: Mapped[str] = mapped_column(String(128), nullable=True)
20+
email: Mapped[str] = mapped_column(String(64), nullable=True)
21+
discord_username: Mapped[str] = mapped_column(String(DISCORD_NICKNAME_LEN), nullable=True)
2222

2323
def to_update_dict(self) -> dict:
2424
return {

src/officers/tables.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
class OfficerTerm(Base):
2929
__tablename__ = "officer_term"
3030

31-
# TODO (#98): create a unique constraint for (computing_id, position, start_date).
3231
id: Mapped[str] = mapped_column(Integer, primary_key=True, autoincrement=True)
3332

3433
computing_id: Mapped[str] = mapped_column(
@@ -38,9 +37,9 @@ class OfficerTerm(Base):
3837
)
3938

4039
position: Mapped[OfficerPositionEnum] = mapped_column(String(128), nullable=False)
41-
start_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
40+
start_date: Mapped[datetime] = mapped_column(DateTime, nullable=False)
4241
# end_date is only not-specified for positions that don't have a length (ie. webmaster)
43-
end_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True)
42+
end_date: Mapped[datetime] = mapped_column(DateTime, nullable=True)
4443

4544
nickname: Mapped[str] = mapped_column(String(128), nullable=True)
4645
favourite_course_0: Mapped[str] = mapped_column(String(64), nullable=True)

0 commit comments

Comments
 (0)