Skip to content

Commit

Permalink
move model forward: subsystems, dataclasses, uid base class
Browse files Browse the repository at this point in the history
  • Loading branch information
ctheune committed Feb 4, 2024
1 parent af8d302 commit 789f9d9
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 18 deletions.
66 changes: 66 additions & 0 deletions src/aramaki/server/alembic/versions/20240204_f342ec229dba.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""add subsystems
Revision ID: f342ec229dba
Revises: d50e144e683a
Create Date: 2024-02-04 09:00:59.137909
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "f342ec229dba"
down_revision = "d50e144e683a"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"subsystem",
sa.Column("system_id", sa.Uuid(), nullable=False),
sa.Column("subsystem_id", sa.Uuid(), nullable=False),
sa.ForeignKeyConstraint(
["subsystem_id"],
["system.id"],
name=op.f("fk_subsystem_subsystem_id_system"),
),
sa.ForeignKeyConstraint(
["system_id"],
["system.id"],
name=op.f("fk_subsystem_system_id_system"),
),
sa.PrimaryKeyConstraint(
"system_id", "subsystem_id", name=op.f("pk_subsystem")
),
)
op.add_column("system", sa.Column("type_", sa.String(), nullable=False))
op.alter_column(
"system", "primary_instance", existing_type=sa.UUID(), nullable=False
)
op.alter_column(
"system",
"title",
existing_type=sa.TEXT(),
type_=sa.String(),
nullable=False,
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"system",
"title",
existing_type=sa.String(),
type_=sa.TEXT(),
nullable=True,
)
op.alter_column(
"system", "primary_instance", existing_type=sa.UUID(), nullable=True
)
op.drop_column("system", "type_")
op.drop_table("subsystem")
# ### end Alembic commands ###
23 changes: 21 additions & 2 deletions src/aramaki/server/models/meta.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
from sqlalchemy.orm import DeclarativeBase
import uuid

from sqlalchemy import func
from sqlalchemy.orm import (
DeclarativeBase,
Mapped,
MappedAsDataclass,
mapped_column,
)
from sqlalchemy.schema import MetaData

# Recommended naming convention used by Alembic, as various different database
Expand All @@ -15,5 +23,16 @@
metadata = MetaData(naming_convention=NAMING_CONVENTION)


class Base(DeclarativeBase):
class Base(MappedAsDataclass, DeclarativeBase):
metadata = metadata


class UIDBase(Base):
__abstract__ = True

id: Mapped[uuid.UUID] = mapped_column(
init=False,
primary_key=True,
default_factory=uuid.uuid4,
server_default=func.gen_random_uuid(),
)
37 changes: 26 additions & 11 deletions src/aramaki/server/models/system.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import uuid

from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import Column, ForeignKey, Table
from sqlalchemy.orm import Mapped, relationship

from . import meta

subsystem = Table(
"subsystem",
meta.Base.metadata,
Column("system_id", ForeignKey("system.id"), primary_key=True),
Column("subsystem_id", ForeignKey("system.id"), primary_key=True),
)

class System(meta.Base):
__tablename__ = "system"

id: Mapped[uuid.UUID] = mapped_column(
primary_key=True,
default=uuid.uuid4,
server_default=func.gen_random_uuid(),
)

title: Mapped[str]
class System(meta.UIDBase):
__tablename__ = "system"

# Make this a dictionary, use references
type_: Mapped[str]

# XXX Turn into relationship
primary_instance: Mapped[uuid.UUID]

title: Mapped[str]

# Subsystems are designed specifically as an n-to-m relation ship with the
# idea that the subsystems itself should be quite independent and that this
# is an organizational relationship for the UI that should be flexible.
#
# To avoid too many implicit dependencies on attributes from the parents
# I'm currently not setting up the inverse relationship. We'll see how
# this goes and whether this can hold over time.
subsystems: Mapped[list["System"]] = relationship(
secondary=subsystem,
primaryjoin="system.c.id == subsystem.c.system_id",
secondaryjoin="system.c.id == subsystem.c.subsystem_id",
default_factory=list,
)
22 changes: 17 additions & 5 deletions src/aramaki/server/tests/test_system.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import uuid

from aramaki.server.models.system import System


def test_system_basic():
system = System()
system = System(
type_="infrastructure", primary_instance="asdf", title="A system"
)

assert isinstance(system.id, uuid.UUID)
assert system.title == "A system"
assert system.type_ == "infrastructure"
assert system.primary_instance == "asdf"
assert system.subsystems == []

subsystem = System(
type_="infrastructure", primary_instance="asdf", title="A subsystem"
)
system.subsystems.append(subsystem)

assert system.id is None
assert system.title is None
assert system.type_ is None
assert system.primary_instance is None
assert system.subsystems == [subsystem]

0 comments on commit 789f9d9

Please sign in to comment.