Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
39ece9a
Moves alembic setups into DashAI package
Creylay Oct 20, 2025
8d14e8b
re-add migrate file. Fix alembic path issues
Creylay Oct 20, 2025
566d480
Refactor database URL resolution logic and integrate into migration p…
Creylay Oct 20, 2025
d8d0b4a
Update database initialization to use migration on startup
Creylay Oct 20, 2025
e9b3bec
re-add migrations ci check
Creylay Oct 20, 2025
59ced82
Adds initial migrations
Creylay Nov 20, 2025
e009ed7
Move alembic.ini and ensure that alembic config is load correcly
Creylay Nov 20, 2025
17fee4f
Add documentation for database migrations and manual execution instru…
Creylay Oct 20, 2025
262d9af
Fix error message for undefined DATABASE_URL in ci_alembic_check.py
Creylay Nov 20, 2025
59506aa
Remove unnecessary blank line in migrate.py
Creylay Nov 20, 2025
fb31ea9
Update pre-commit configuration to enable verbose output for ruff
Creylay Nov 20, 2025
38b1f3e
Refactor pre-commit workflow for consistency and clarity in naming co…
Creylay Nov 20, 2025
aad1d18
Update ruff arguments to use --show-fixes for clearer output
Creylay Nov 20, 2025
c11238e
Merge branch 'develop' into feature/redo-db-migrations
Creylay Dec 22, 2025
34fad91
New initial migration
Creylay Dec 23, 2025
ca66829
Reorder import statements in migration scripts for ruff check
Creylay Dec 23, 2025
04229ab
Update MANIFEST.in to include types folder
Creylay Dec 24, 2025
bcc945f
Add column type display to DivideDatasetColumns and integrate dataset…
Creylay Dec 19, 2025
a07329d
Refactor rendering of tags in DivideDatasetColumns to remove unnecess…
Creylay Dec 19, 2025
f1010cb
Add column type color display in DivideDatasetColumns and PrepareData…
Creylay Jan 5, 2026
d32c582
feat: enhance BaseModel with train abstract method and metric calcula…
Irozuku Dec 22, 2025
5f7c953
fix: prevent loading data when x_data or y_data is not set in BaseModel
Irozuku Dec 23, 2025
cbe45a4
feat: add Metric model to store metric information related to runs
Irozuku Dec 23, 2025
e5a867d
feat: enhance ModelJob and ModelFactory to support metric calculation…
Irozuku Dec 23, 2025
244d051
feat: rename fit method to train in bow text classification model
Irozuku Dec 23, 2025
cea3357
feat: add MetricsCallback class for training and validation metric ca…
Irozuku Dec 23, 2025
862ccb7
feat: refactor training methods and integrate MetricsCallback for per…
Irozuku Dec 23, 2025
7c8e47d
feat: rename fit method to train for consistency with model training …
Irozuku Dec 23, 2025
9b9dc38
feat: add live metrics websocket endpoint for real-time metric updates
Irozuku Dec 23, 2025
ad9bbe6
feat: add metric deletion on run reset to maintain database integrity
Irozuku Dec 23, 2025
9f25075
fix: replace fit with train in tests for consistency
Irozuku Dec 23, 2025
9fbe31c
feat: integrate LiveMetricsChart component to display real-time metri…
Irozuku Dec 23, 2025
532775c
feat: add metrics per split to Experiment model and update ModelJob t…
Irozuku Dec 23, 2025
859a8c7
feat: add train, validation, and test metrics to Experiment creation
Irozuku Dec 23, 2025
880fe33
feat: implement metrics selection for experiment configuration
Irozuku Dec 23, 2025
2d39421
fix: ensure metrics display as fixed decimal values in MetricsCard
Irozuku Dec 23, 2025
6a577f6
feat: filter metrics in ResultsTable and format values in extractColumns
Irozuku Dec 23, 2025
47e9889
style: change position of live metrics to display it before last metrics
Irozuku Dec 23, 2025
3765ceb
feat: enhance LiveMetricsChart to load and display test metrics via W…
Irozuku Dec 23, 2025
d33bbdc
fix: add metrics placeholders to experiment creation in test files
Irozuku Dec 23, 2025
8f9902c
fix: remove unnecessary blank line in live_metrics_websocket function
Irozuku Dec 23, 2025
489d6cf
feat: add function to retrieve train, validation, and test metrics fo…
Irozuku Dec 23, 2025
463e4c2
refactor: remove commented-out step-level metrics calculation in Metr…
Irozuku Dec 23, 2025
609deae
feat: streamline metric selection and improve chart rendering logic i…
Irozuku Dec 23, 2025
18c31a2
feat: implement PyTorch MLP regression model and update schema fields
Irozuku Dec 23, 2025
03ea524
fix: add missing commas for consistency in MetricCard, MetricsSelecto…
Irozuku Dec 23, 2025
3f4dc58
feat: enhance OptunaOptimizer to calculate metrics for train and vali…
Irozuku Dec 24, 2025
ce516f4
feat: enhance HyperOptOptimizer to calculate metrics for train and va…
Irozuku Dec 24, 2025
58a903d
fix: add prepare_to_metric function for preprocessing true and predic…
Irozuku Dec 24, 2025
65134ed
fix: refactor BagOfWordsTextClassificationModel removing SklearnLikeM…
Irozuku Dec 24, 2025
6080a4e
fix: remove unused SklearnLikeModel import from BagOfWordsTextClassif…
Irozuku Dec 24, 2025
07192ff
fix: refactor MLPRegression to flatten model output and include input…
Irozuku Dec 29, 2025
4f37d39
feat: add DESCRIPTION attribute to classification and regression metr…
Irozuku Dec 24, 2025
dfa0907
feat: add support for minimize/maximize indicators in MetricCard comp…
Irozuku Dec 24, 2025
20e4de8
feat: add new classification metrics including Cohen Kappa, Hamming D…
Irozuku Dec 26, 2025
4da1d9b
feat: add new regression metrics including MSE, R2, Explained Varianc…
Irozuku Dec 26, 2025
9217fa8
fix: improve description formatting in Median Absolute Error and MSE …
Irozuku Dec 26, 2025
c2879de
feat: add CHRF metric for translation tasks and update requirements
Irozuku Dec 26, 2025
a96a2d4
fix: add metrics relationship to Run and enhance Metric model with ad…
Irozuku Dec 30, 2025
2d49702
refactor: enhance live_metrics_websocket to structure payload with ne…
Irozuku Dec 30, 2025
e3b3ee5
refactor: enhance _save_metrics and calculate_metrics methods to supp…
Irozuku Dec 30, 2025
62ae5f3
refactor: add logging configuration for training and validation metri…
Irozuku Dec 30, 2025
691dad5
refactor: enhance MLPRegressorSchema and MLPRegression for improved m…
Irozuku Dec 30, 2025
d3125fb
refactor: streamline metric retrieval in get_metrics_for_run
Irozuku Dec 30, 2025
4604f37
refactor: update LiveMetricsChart to support new metric data structur…
Irozuku Dec 30, 2025
10e0d4f
refactor: update MetricsCard and ResultsTable for to support new metr…
Irozuku Dec 30, 2025
b83350b
fix: add logging frequency parameters to distilbert model in test
Irozuku Dec 30, 2025
d1836ff
refactor: optimize live metrics websocket handling and improve metric…
Irozuku Dec 31, 2025
1624d21
feat: add initial database migrations for core tables
Creylay Jan 7, 2026
7cdc14f
docs: enhance database migrations section in README
Creylay Jan 7, 2026
eb5c438
Merge remote-tracking branch 'origin/develop' into feature/redo-db-mi…
Creylay Jan 19, 2026
8c9d5ff
feat: add model_session table and update run table for migration
Creylay Jan 19, 2026
d466d45
feat: update model_session creation and modify run table for migration
Creylay Jan 19, 2026
5cd5c39
feat: update Base declaration to include metadata and naming conventions
Creylay Jan 19, 2026
ed54e25
feat: create model_session table and update run table for migration
Creylay Jan 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/workflows/db-migrations.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: DB Migrations

on:
push:
branches:
- develop
pull_request:
workflow_dispatch:

jobs:
alembic-migrations:
strategy:
matrix:
python-version: ["3.10"]

runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
pip install --upgrade --upgrade-strategy eager -r requirements.txt
pip install --upgrade --upgrade-strategy eager -r requirements-dev.txt

- name: Set DB env vars
run: |
echo "DB_FILE=$RUNNER_TEMP/dashai-ci.sqlite3" >> "$GITHUB_ENV"
echo "DATABASE_URL=sqlite:///$RUNNER_TEMP/dashai-ci.sqlite3" >> "$GITHUB_ENV"
echo "Temp dir: $RUNNER_TEMP"

- name: Show Alembic info
run: |
alembic --version
echo "DB will be at: $DATABASE_URL"

- name: Prepare temp dir
run: |
mkdir -p "$(dirname "$DB_FILE")"
rm -f "$DB_FILE"

# upgrade to head
- name: Upgrade to head
run: |
alembic -x url="$DATABASE_URL" upgrade head

# Checks downgrade and upgrade again (reversibility)
- name: Downgrade to base and upgrade again (reversibility check)
run: |
alembic -x url="$DATABASE_URL" downgrade base
alembic -x url="$DATABASE_URL" upgrade head

- name: Check for pending autogenerate (python-based)
env:
PYTHONPATH: "${PYTHONPATH}:."
run: python -m scripts.ci_alembic_check
15 changes: 8 additions & 7 deletions .github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
name: Pre-commit checks
on:
push
on: push
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: 'Check out repository code'
- name: "Check out repository code"
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'yarn'
node-version: "18.x"
cache: "yarn"
cache-dependency-path: DashAI/front/yarn.lock

- name: Install frontend deps
working-directory: DashAI/front
run: yarn install --frozen-lockfile

- name: Setup latest Python 3.x
uses: actions/setup-python@v3
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install pre-commit
run: |
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ repos:
rev: v0.12.10
hooks:
- id: ruff
args: [--fix]
args: [--fix, "--show-fixes"]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v4.0.0-alpha.8"
hooks:
- id: prettier
files: \.[jt]sx?$ # *.js, *.jsx, *.ts, *.tsx
files: \.[jt]sx?$ # *.js, *.jsx, *.ts, *.tsx
types: [file]
args:
- "--config=DashAI/front/.prettierrc"
Expand Down
91 changes: 91 additions & 0 deletions DashAI/alembic/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import os
from pathlib import Path
from logging.config import fileConfig

from sqlalchemy import engine_from_config, pool
from alembic import context

from DashAI.back.dependencies.database import Base

config = context.config


def _resolve_url() -> str:
"""
Prioridad url sql:
1) alembic -x url=...
2) env var DATABASE_URL
3) value already present in alembic.ini (config.get_main_option)
4) fallback using the same logic as the application (~/.DashAI/db.sqlite)
"""
# 1) cli -x url
xargs = context.get_x_argument(as_dictionary=True)
if xargs and xargs.get("url"):
return xargs["url"]

# 2) environment
env_url = os.getenv("DATABASE_URL")
if env_url:
return env_url

# 3) value from alembic.ini (if any)
cfg_url = config.get_main_option("sqlalchemy.url")
if cfg_url and cfg_url != "sqlite:///":
return cfg_url

# 4) fallback - same as application config
# Use the same default path as the application: ~/.DashAI/db.sqlite
from DashAI.back.config import DefaultSettings
settings = DefaultSettings()
local_path = Path(settings.LOCAL_PATH).expanduser().absolute()
db_path = local_path / settings.SQLITE_DB_PATH
return f"sqlite:///{db_path}"


config.set_main_option("sqlalchemy.url", _resolve_url())

if config.config_file_name is not None:
fileConfig(config.config_file_name)

target_metadata = Base.metadata


def run_migrations_offline():
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
compare_type=True,
compare_server_default=True,
)
with context.begin_transaction():
context.run_migrations()


def run_migrations_online():
ini = dict(config.get_section(config.config_ini_section) or {})

connectable = engine_from_config(
ini,
prefix="sqlalchemy.",
poolclass=pool.NullPool,
future=True,
)

with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True,
compare_server_default=True,
render_as_batch=True,
)
with context.begin_transaction():
context.run_migrations()


if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
10 changes: 6 additions & 4 deletions alembic/script.py.mako → DashAI/alembic/script.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ 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 = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
branch_labels = ${repr(branch_labels)}
depends_on = ${repr(depends_on)}
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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Experiments to model session

Revision ID: 57ff87150ae2
Revises: 7662169fa0e0
Create Date: 2026-01-19 16:14:03.739306

"""
from typing import Sequence, Union

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

# revision identifiers, used by Alembic.
revision: str = '57ff87150ae2'
down_revision: Union[str, None] = '7662169fa0e0'
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('model_session',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('dataset_id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('task_name', sa.String(), nullable=False),
sa.Column('input_columns', sa.JSON(), nullable=False),
sa.Column('output_columns', sa.JSON(), nullable=False),
sa.Column('train_metrics', sa.JSON(), nullable=True),
sa.Column('validation_metrics', sa.JSON(), nullable=True),
sa.Column('test_metrics', sa.JSON(), nullable=True),
sa.Column('splits', sa.JSON(), nullable=False),
sa.Column('created', sa.DateTime(), nullable=False),
sa.Column('last_modified', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['dataset_id'], ['dataset.id'], name=op.f('fk_model_session_dataset_id_dataset')),
sa.PrimaryKeyConstraint('id', name=op.f('pk_model_session')),
sa.UniqueConstraint('name', name=op.f('uq_model_session_name'))
)
with op.batch_alter_table('run', schema=None) as batch_op:
batch_op.add_column(sa.Column('model_session_id', sa.Integer(), nullable=False))
batch_op.drop_constraint(batch_op.f('fk_run_experiment_id_experiment'), type_='foreignkey')
batch_op.create_foreign_key(batch_op.f('fk_run_model_session_id_model_session'), 'model_session', ['model_session_id'], ['id'], ondelete='CASCADE')
batch_op.drop_column('experiment_id')
op.drop_table('experiment')

# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('run', schema=None) as batch_op:
batch_op.add_column(sa.Column('experiment_id', sa.INTEGER(), nullable=False))
batch_op.drop_constraint(batch_op.f('fk_run_model_session_id_model_session'), type_='foreignkey')
batch_op.create_foreign_key(batch_op.f('fk_run_experiment_id_experiment'), 'experiment', ['experiment_id'], ['id'], ondelete='CASCADE')
batch_op.drop_column('model_session_id')

op.create_table('experiment',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('dataset_id', sa.INTEGER(), nullable=False),
sa.Column('name', sa.VARCHAR(), nullable=False),
sa.Column('task_name', sa.VARCHAR(), nullable=False),
sa.Column('input_columns', sqlite.JSON(), nullable=False),
sa.Column('output_columns', sqlite.JSON(), nullable=False),
sa.Column('train_metrics', sqlite.JSON(), nullable=True),
sa.Column('validation_metrics', sqlite.JSON(), nullable=True),
sa.Column('test_metrics', sqlite.JSON(), nullable=True),
sa.Column('splits', sqlite.JSON(), nullable=False),
sa.Column('created', sa.DATETIME(), nullable=False),
sa.Column('last_modified', sa.DATETIME(), nullable=False),
sa.ForeignKeyConstraint(['dataset_id'], ['dataset.id'], name=op.f('fk_experiment_dataset_id_dataset')),
sa.PrimaryKeyConstraint('id', name=op.f('pk_experiment')),
sa.UniqueConstraint('name', name=op.f('uq_experiment_name'))
)
op.drop_table('model_session')
# ### end Alembic commands ###
Loading