Skip to content

Commit

Permalink
Merge pull request #593 from stacklok/db-migrations
Browse files Browse the repository at this point in the history
feat: Introduce DB migrations
  • Loading branch information
aponcedeleonch authored Jan 15, 2025
2 parents 7022d28 + 34907a9 commit 7593f72
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 85 deletions.
19 changes: 19 additions & 0 deletions alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Database configuration.
# See the full list of options at:
# https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file

[alembic]
# path to migration scripts
# Use forward slashes (/) also on windows to provide an os agnostic path
script_location = migrations

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .

# version path separator; is the character used to split
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
version_path_separator = os # Use os.pathsep.

# DB connection string
sqlalchemy.url = sqlite:///codegate_volume/db/codegate.db
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
67 changes: 67 additions & 0 deletions migrations/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from alembic import context
from sqlalchemy import engine_from_config, pool

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)

with context.begin_transaction():
context.run_migrations()


def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
print(config.config_ini_section)
with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)

with context.begin_transaction():
context.run_migrations()


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
26 changes: 26 additions & 0 deletions migrations/script.py.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""${message}

Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
${imports if imports else ""}

# revision identifiers, used by Alembic.
revision: str = ${repr(up_revision)}
down_revision: Union[str, None] = ${repr(down_revision)}
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}


def upgrade() -> None:
${upgrades if upgrades else "pass"}


def downgrade() -> None:
${downgrades if downgrades else "pass"}
83 changes: 83 additions & 0 deletions migrations/versions/30d0144e1a50_init_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""init db
Revision ID: 30d0144e1a50
Revises:
Create Date: 2025-01-15 09:30:00.490697
"""

from typing import Sequence, Union

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "30d0144e1a50"
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:
# Schema for codegate database using SQLite
# Prompts table
op.execute(
"""
CREATE TABLE prompts (
id TEXT PRIMARY KEY, -- UUID stored as TEXT
timestamp DATETIME NOT NULL,
provider TEXT, -- VARCHAR(255)
request TEXT NOT NULL, -- Record the full request that arrived to the server
type TEXT NOT NULL -- VARCHAR(50) (e.g. "fim", "chat")
);
"""
)
# Outputs table
op.execute(
"""
CREATE TABLE outputs (
id TEXT PRIMARY KEY, -- UUID stored as TEXT
prompt_id TEXT NOT NULL,
timestamp DATETIME NOT NULL,
output TEXT NOT NULL, -- Record the full response. If stream will be a list of objects
FOREIGN KEY (prompt_id) REFERENCES prompts(id)
);
"""
)
# Alerts table
op.execute(
"""
CREATE TABLE alerts (
id TEXT PRIMARY KEY, -- UUID stored as TEXT
prompt_id TEXT NOT NULL,
code_snippet TEXT,
trigger_string TEXT, -- VARCHAR(255)
trigger_type TEXT NOT NULL, -- VARCHAR(50)
trigger_category TEXT,
timestamp DATETIME NOT NULL,
FOREIGN KEY (prompt_id) REFERENCES prompts(id)
);
"""
)
# Settings table
op.execute(
"""
CREATE TABLE settings (
id TEXT PRIMARY KEY, -- UUID stored as TEXT
ip TEXT, -- VARCHAR(45)
port INTEGER,
llm_model TEXT, -- VARCHAR(255)
system_prompt TEXT,
other_settings TEXT -- JSON stored as TEXT
);
"""
)
# Create indexes for foreign keys and frequently queried columns
op.execute("CREATE INDEX idx_outputs_prompt_id ON outputs(prompt_id);")
op.execute("CREATE INDEX idx_alerts_prompt_id ON alerts(prompt_id);")
op.execute("CREATE INDEX idx_prompts_timestamp ON prompts(timestamp);")
op.execute("CREATE INDEX idx_outputs_timestamp ON outputs(timestamp);")
op.execute("CREATE INDEX idx_alerts_timestamp ON alerts(timestamp);")


def downgrade() -> None:
pass
44 changes: 42 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ tree-sitter-javascript = ">=0.23.1"
tree-sitter-python = ">=0.23.6"
tree-sitter-rust = ">=0.23.2"
sqlite-vec-sl-tmp = "^0.0.4"
alembic = ">=1.14.0"

[tool.poetry.group.dev.dependencies]
pytest = ">=7.4.0"
Expand Down
48 changes: 0 additions & 48 deletions sql/schema/schema.sql

This file was deleted.

Loading

0 comments on commit 7593f72

Please sign in to comment.