Skip to content

Commit

Permalink
feat: Setup Initial Migrations with Alembic
Browse files Browse the repository at this point in the history
  • Loading branch information
katsujukou committed Dec 27, 2024
1 parent 1de6fd3 commit db0d016
Show file tree
Hide file tree
Showing 11 changed files with 281 additions and 307 deletions.
22 changes: 15 additions & 7 deletions backend/alembic/env.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from logging.config import fileConfig
from os import environ

import sqlalchemy as sa
from alembic import context
from alembic.autogenerate import renderers
from oqtopus_cloud.common.models import Base
from sqlalchemy import TypeDecorator, engine_from_config, pool
from sqlalchemy import Enum, TypeDecorator, engine_from_config, pool

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
Expand All @@ -25,14 +27,18 @@
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

enum_field_max_length = 64

def render_item(type_, obj, autogen_context):
"""Apply custom rendering for selected items."""

if type_ == "type" and isinstance(obj, TypeDecorator):
return f"sa.{obj.impl!r}"
def render_enum(type_, obj, autogen_context):
if type_ == "type" and isinstance(obj, sa.Enum):
# Check for enum's members having name of acceptable length.
# (...or, There might be more preferable ways than raising exception?)
for member in obj.enums:
if len(member) >= enum_field_max_length:
raise ValueError(f"Enum field `{member}` is too long.")
return f"sa.String(length={enum_field_max_length})"

# default rendering for other objects
return False


Expand Down Expand Up @@ -62,6 +68,7 @@ def run_migrations_offline() -> None:
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
compare_server_default=True,
)

with context.begin_transaction():
Expand Down Expand Up @@ -89,7 +96,8 @@ def run_migrations_online() -> None:
context.configure(
connection=connection,
target_metadata=target_metadata,
render_item=render_item,
render_item=render_enum,
compare_server_default=True,
)

with context.begin_transaction():
Expand Down
45 changes: 0 additions & 45 deletions backend/alembic/versions/20240911__38a0365a40fd__create_devices.py

This file was deleted.

This file was deleted.

This file was deleted.

63 changes: 63 additions & 0 deletions backend/alembic/versions/20241227__4259239bd704__create_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""create_tables
Revision ID: 4259239bd704
Revises:
Create Date: 2024-12-27 15:53:59.225458
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '4259239bd704'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('devices',
sa.Column('id', sa.String(length=64), nullable=False),
sa.Column('device_type', sa.String(length=64), nullable=False),
sa.Column('status', sa.String(length=64), nullable=False),
sa.Column('available_at', sa.DateTime(), nullable=True),
sa.Column('pending_jobs', sa.Integer(), nullable=False),
sa.Column('n_qubits', sa.Integer(), nullable=False),
sa.Column('basis_gates', sa.String(length=256), nullable=False),
sa.Column('instructions', sa.String(length=64), nullable=False),
sa.Column('device_info', sa.Text(), nullable=False),
sa.Column('calibrated_at', sa.DateTime(), nullable=False),
sa.Column('description', sa.String(length=128), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('jobs',
sa.Column('id', sa.String(length=64), nullable=False),
sa.Column('owner', sa.String(length=64), nullable=False),
sa.Column('name', sa.String(length=256), nullable=True),
sa.Column('description', sa.String(length=1024), nullable=True),
sa.Column('device_id', sa.String(length=64), nullable=False),
sa.Column('job_info', sa.Text(), nullable=False),
sa.Column('transpiler_info', sa.Text(), nullable=False),
sa.Column('simulator_info', sa.Text(), nullable=False),
sa.Column('mitigation_info', sa.Text(), nullable=False),
sa.Column('job_type', sa.String(length=64), nullable=False),
sa.Column('shots', sa.Integer(), nullable=True),
sa.Column('status', sa.String(length=32), nullable=False),
sa.Column('created_at', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), nullable=True),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('jobs')
op.drop_table('devices')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""set_jobs_status_default
Revision ID: 6bd5dd2dc2ce
Revises: 4259239bd704
Create Date: 2024-12-27 15:56:56.786646
"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision: str = "6bd5dd2dc2ce"
down_revision: Union[str, None] = "4259239bd704"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"jobs",
"status",
existing_type=mysql.VARCHAR(collation="utf8mb4_unicode_ci", length=32),
server_default="submitted",
existing_nullable=False,
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"jobs",
"status",
existing_type=mysql.VARCHAR(collation="utf8mb4_unicode_ci", length=32),
server_default=None,
existing_nullable=False,
)
# ### end Alembic commands ###
15 changes: 12 additions & 3 deletions backend/oqtopus_cloud/common/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Don't erase this definition, it is used to import all models in the api.models package
# https://stackoverflow.com/questions/7478403/sqlalchemy-classes-across-files
# if table has foreign key, it should be imported in the same file
__all__ = ["Device", "Job", "Base"]
__all__ = [
"Base",
"DeviceId",
"DeviceStatus",
"Device",
"JobId",
"Job",
"JobStatus",
"Base",
]
from oqtopus_cloud.common.models.base import Base
from oqtopus_cloud.common.models.device import Device
from oqtopus_cloud.common.models.job import Job
from oqtopus_cloud.common.models.device import Device, DeviceId, DeviceStatus
from oqtopus_cloud.common.models.job import Job, JobId, JobStatus
Loading

0 comments on commit db0d016

Please sign in to comment.