Compare commits
1 Commits
4b91effee3
...
fix/runtim
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41fb54c5e7 |
@@ -58,7 +58,7 @@ docker compose up --build
|
|||||||
- MCP: `http://localhost:8001/mcp`
|
- MCP: `http://localhost:8001/mcp`
|
||||||
- Postgres: `localhost:5432`
|
- Postgres: `localhost:5432`
|
||||||
|
|
||||||
Таблицы создаются приложением при старте. SQL-миграция для ручного применения лежит в `migrations/001_init.sql`.
|
Таблицы создаются приложением при старте. При обновлении существующей базы приложение также добавляет недостающие runtime-колонки, например `crawl_runs.skipped_count`. SQL-миграции для ручного применения лежат в `migrations/`.
|
||||||
|
|
||||||
## Парсинг
|
## Парсинг
|
||||||
|
|
||||||
@@ -115,4 +115,4 @@ docker compose exec postgres pg_dump -U miem miem_workers > backup.sql
|
|||||||
docker compose down
|
docker compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
Версия сервиса: `0.6.0`. Админка всегда показывает версии backend и frontend в footer.
|
Версия сервиса: `0.6.1`. Админка всегда показывает версии backend и frontend в footer.
|
||||||
|
|||||||
13
app/db.py
13
app/db.py
@@ -1,6 +1,6 @@
|
|||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine, inspect, text
|
||||||
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
||||||
|
|
||||||
from app.config import get_settings
|
from app.config import get_settings
|
||||||
@@ -25,6 +25,17 @@ def init_db() -> None:
|
|||||||
import app.models # noqa: F401
|
import app.models # noqa: F401
|
||||||
|
|
||||||
Base.metadata.create_all(bind=engine)
|
Base.metadata.create_all(bind=engine)
|
||||||
|
_ensure_runtime_schema()
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_runtime_schema() -> None:
|
||||||
|
inspector = inspect(engine)
|
||||||
|
if "crawl_runs" not in inspector.get_table_names():
|
||||||
|
return
|
||||||
|
crawl_run_columns = {column["name"] for column in inspector.get_columns("crawl_runs")}
|
||||||
|
if "skipped_count" not in crawl_run_columns:
|
||||||
|
with engine.begin() as connection:
|
||||||
|
connection.execute(text("ALTER TABLE crawl_runs ADD COLUMN skipped_count INTEGER NOT NULL DEFAULT 0"))
|
||||||
|
|
||||||
|
|
||||||
def get_db() -> Generator[Session, None, None]:
|
def get_db() -> Generator[Session, None, None]:
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
APP_VERSION = "0.6.0"
|
APP_VERSION = "0.6.1"
|
||||||
FRONTEND_VERSION = "0.6.0"
|
FRONTEND_VERSION = "0.6.1"
|
||||||
BACKEND_VERSION = "0.6.0"
|
BACKEND_VERSION = "0.6.1"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "miem-workers"
|
name = "miem-workers"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
description = "MIEM employees parser, admin API, and MCP server"
|
description = "MIEM employees parser, admin API, and MCP server"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def test_health_returns_versions():
|
|||||||
response = client.get("/api/health")
|
response = client.get("/api/health")
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json()["backend_version"] == "0.6.0"
|
assert response.json()["backend_version"] == "0.6.1"
|
||||||
|
|
||||||
|
|
||||||
def test_mcp_lists_tools_without_auth_and_ignores_auth_header():
|
def test_mcp_lists_tools_without_auth_and_ignores_auth_header():
|
||||||
@@ -154,7 +154,7 @@ def test_mcp_service_info_returns_tools_and_dataset_hash():
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
payload = json.loads(response.json()["result"]["content"][0]["text"])
|
payload = json.loads(response.json()["result"]["content"][0]["text"])
|
||||||
assert payload["service_name"] == "miem-employees"
|
assert payload["service_name"] == "miem-employees"
|
||||||
assert payload["backend_version"] == "0.6.0"
|
assert payload["backend_version"] == "0.6.1"
|
||||||
assert payload["dataset"]["hash"]
|
assert payload["dataset"]["hash"]
|
||||||
assert any(tool["name"] == "sync_employees" for tool in payload["tools"])
|
assert any(tool["name"] == "sync_employees" for tool in payload["tools"])
|
||||||
|
|
||||||
|
|||||||
27
tests/test_db_schema.py
Normal file
27
tests/test_db_schema.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from sqlalchemy import create_engine, inspect, text
|
||||||
|
|
||||||
|
from app.db import _ensure_runtime_schema
|
||||||
|
|
||||||
|
|
||||||
|
def test_runtime_schema_adds_skipped_count_to_existing_crawl_runs_table(monkeypatch):
|
||||||
|
engine = create_engine("sqlite:///:memory:")
|
||||||
|
with engine.begin() as connection:
|
||||||
|
connection.execute(
|
||||||
|
text(
|
||||||
|
"""
|
||||||
|
CREATE TABLE crawl_runs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
source_url TEXT NOT NULL,
|
||||||
|
status VARCHAR(32) NOT NULL DEFAULT 'running',
|
||||||
|
found_count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
parsed_count INTEGER NOT NULL DEFAULT 0
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
monkeypatch.setattr("app.db.engine", engine)
|
||||||
|
|
||||||
|
_ensure_runtime_schema()
|
||||||
|
|
||||||
|
columns = {column["name"] for column in inspect(engine).get_columns("crawl_runs")}
|
||||||
|
assert "skipped_count" in columns
|
||||||
Reference in New Issue
Block a user