From b95b7caefd24652c1bf12ddcd4a41e04e8334bb1 Mon Sep 17 00:00:00 2001 From: TheNoxium Date: Fri, 28 Mar 2025 17:32:57 +0500 Subject: [PATCH 1/3] feat: added sql tables and db connection --- api/api/config/default.py | 20 +++++ api/api/db/connection/session.py | 63 +++++++++++++++ api/api/db/tables/__init__.py | 1 + api/api/db/tables/account.py | 57 +++++++++++++ api/api/db/tables/events.py | 29 +++++++ api/api/db/tables/process.py | 80 +++++++++++++++++++ api/api/schemas/account/__init__.py | 0 api/api/schemas/account/account.py | 30 +++++++ api/api/schemas/account/account_keyring.py | 27 +++++++ api/api/schemas/events/__init__.py | 0 api/api/schemas/events/list_events.py | 25 ++++++ api/api/schemas/process/__init__.py | 0 api/api/schemas/process/node_link.py | 20 +++++ api/api/schemas/process/process_schema.py | 20 +++++ .../process/process_version_archive.py | 11 +++ api/api/schemas/process/ps_node.py | 23 ++++++ 16 files changed, 406 insertions(+) create mode 100644 api/api/db/connection/session.py create mode 100644 api/api/db/tables/account.py create mode 100644 api/api/db/tables/events.py create mode 100644 api/api/db/tables/process.py create mode 100644 api/api/schemas/account/__init__.py create mode 100644 api/api/schemas/account/account.py create mode 100644 api/api/schemas/account/account_keyring.py create mode 100644 api/api/schemas/events/__init__.py create mode 100644 api/api/schemas/events/list_events.py create mode 100644 api/api/schemas/process/__init__.py create mode 100644 api/api/schemas/process/node_link.py create mode 100644 api/api/schemas/process/process_schema.py create mode 100644 api/api/schemas/process/process_version_archive.py create mode 100644 api/api/schemas/process/ps_node.py diff --git a/api/api/config/default.py b/api/api/config/default.py index 65483b5..3b3b025 100644 --- a/api/api/config/default.py +++ b/api/api/config/default.py @@ -43,6 +43,26 @@ class DefaultSettings(BaseSettings): REDIS_DB: int = int(environ.get("REDIS_DB", "0")) REDIS_PASSWORD: str = environ.get("REDIS_PASSWORD", "hackme") + @property + def database_settings(self) -> dict: + """Get all settings for connection with database.""" + return { + "database": self.MYSQL_DB, + "user": self.MYSQL_USER, + "password": self.MYSQL_PASSWORD, + "host": self.MYSQL_HOST, + "port": self.MYSQL_PORT, + } + + @property + def database_uri(self) -> str: + """Get uri for connection with database.""" + uri = "mysql+aiomysql://{user}:{password}@{host}:{port}/{database}".format( + **self.database_settings, + ) + print("database_uri", uri) + return uri + class Config: # env_file = "../.env" env_file_encoding = "utf-8" diff --git a/api/api/db/connection/session.py b/api/api/db/connection/session.py new file mode 100644 index 0000000..1137f39 --- /dev/null +++ b/api/api/db/connection/session.py @@ -0,0 +1,63 @@ +import contextlib +import json +import os +from typing import Any, AsyncGenerator + +import asyncio + +import sqlalchemy +from loguru import logger +from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine +from sqlalchemy import URL,create_engine, text + + +from api.config import get_settings +from api.config.default import DbCredentialsSchema + + + +class SessionManager: + engines: Any + + + def __init__(self, database_uri=get_settings().database_uri) -> None: + self.database_uri = database_uri + self.refresh(database_uri) + # self.reflect() + + def __new__(cls, database_uri=get_settings().database_uri): + if not hasattr(cls, "instance"): + cls.instance = super(SessionManager, cls).__new__(cls) + cls.instance.engines = {} + return cls.instance + + def refresh(self, database_uri) -> None: + # if not self.engines: + # self.engines = {} + if database_uri not in self.engines: + self.engines[database_uri] = create_async_engine( + database_uri, + echo=True, + future=True, + # json_serializer=serializer, + pool_recycle=1800, + pool_size=get_settings().CONNECTION_POOL_SIZE, + max_overflow=get_settings().CONNECTION_OVERFLOW, + ) + def get_engine_by_db_uri(self, database_uri) -> AsyncEngine: + return self.engines[database_uri] + +@contextlib.asynccontextmanager +async def get_connection( + database_uri=None, +) -> AsyncGenerator[AsyncConnection, None]: + if not database_uri: + database_uri = get_settings().database_uri + engine = SessionManager(database_uri).get_engine_by_db_uri(database_uri) + logger.debug(f"engine {engine} {SessionManager(database_uri).engines}") + async with engine.connect() as conn: + yield conn + +async def get_connection_dep() -> AsyncConnection: + async with get_connection() as conn: + yield conn diff --git a/api/api/db/tables/__init__.py b/api/api/db/tables/__init__.py index e69de29..d531ebd 100644 --- a/api/api/db/tables/__init__.py +++ b/api/api/db/tables/__init__.py @@ -0,0 +1 @@ +from . import account,events,process diff --git a/api/api/db/tables/account.py b/api/api/db/tables/account.py new file mode 100644 index 0000000..07ffe3f --- /dev/null +++ b/api/api/db/tables/account.py @@ -0,0 +1,57 @@ +from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, MetaData +from sqlalchemy.sql import func +from enum import Enum, auto +from api.db import metadata + + +class AccountRole(str,Enum): + OWNER = auto() + ADMIN = auto() + EDITOR = auto() + VIEWER = auto() + +class AccountStatus(str,Enum): + ACTIVE = auto() + DISABLED = auto() + BLOCKED = auto() + DELETED = auto() + + + +account_table = Table( + 'account', metadata, + Column('id', Integer, primary_key=True, autoincrement=True), + Column('name', String(100), nullable=False), + Column('login', String(100), nullable=False), + Column('email', String(100), nullable=True), + Column('bind_tenant_id', String(40), nullable=True), + Column('role', SQLAEnum(AccountRole), nullable=False), + Column('meta', JSON, default={}), + Column('creator_id', Integer, ForeignKey('account.id'), nullable=True), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('status', SQLAEnum(AccountStatus), nullable=False), + + Index('idx_login', 'login'), + Index('idx_name', 'name'), +) + +class KeyType(str,Enum): + PASSWORD = auto() + ACCESS_TOKEN = auto() + REFRESH_TOKEN = auto() + API_KEY = auto() + +class KeyStatus(str,Enum): + ACTIVE = auto() + EXPIRED = auto() + DELETED = auto() + +account_keyring_table = Table( + 'account_keyring', metadata, + Column('owner_id', Integer, ForeignKey('account.id'), primary_key=True, nullable=False), + Column('key_type', SQLAEnum(KeyType), primary_key=True, nullable=False), + Column('key_id', String(40), default=None), + Column('key_value', String(64), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('expiry', DateTime(timezone=True), nullable=True), + Column('status', SQLAEnum(KeyStatus), nullable=False), ) diff --git a/api/api/db/tables/events.py b/api/api/db/tables/events.py new file mode 100644 index 0000000..51179cf --- /dev/null +++ b/api/api/db/tables/events.py @@ -0,0 +1,29 @@ +from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index +from sqlalchemy.sql import func +from enum import Enum, auto +from api.db import metadata + +class EventState(str, Enum): + AUTO = auto() + DESCRIPTED = auto() + +class EventStatus(str, Enum): + ACTIVE = auto() + DISABLED = auto() + DELETED = auto() + + +list_events_table = Table( + 'list_events', metadata, + Column('id', Integer, primary_key=True, autoincrement=True), + Column('name', String(40, collation='latin1_bin'), nullable=False), + Column('title', String(64), nullable=False), + Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('schema', JSON, default={}), + Column('state', SQLAEnum(EventState), nullable=False), + Column('status', SQLAEnum(EventStatus), nullable=False), + + + Index('UNIQUE_name', 'name', unique=True) +) diff --git a/api/api/db/tables/process.py b/api/api/db/tables/process.py new file mode 100644 index 0000000..0d98353 --- /dev/null +++ b/api/api/db/tables/process.py @@ -0,0 +1,80 @@ +from sqlalchemy import Table, Column, Integer, String, Text, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, PrimaryKeyConstraint +from sqlalchemy.sql import func +from enum import Enum, auto +from api.db import metadata + + +# Определение перечислений для статуса процесса +class ProcessStatus(str, Enum): + ACTIVE = auto() + STOPPING = auto() + STOPPED = auto() + DELETED = auto() + +# Определение таблицы process_schema +process_schema_table = Table( + 'process_schema', metadata, + Column('id', Integer, primary_key=True, autoincrement=True), + Column('title', String(100), nullable=False), + Column('description', Text, nullable=False), + Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('settings', JSON, default={}), + Column('status', SQLAEnum(ProcessStatus), nullable=False), + + Index('idx_owner_id', 'owner_id',) +) + +process_version_archive_table = Table( + 'process_version_archive', metadata, + Column('id', Integer, autoincrement=True, nullable=False), + Column('version', Integer, default=1, nullable=False), + Column('snapshot', JSON, default={}), + Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('is_last', Integer, default=0), + PrimaryKeyConstraint('id', 'version') ) + +class NodeStatus(str, Enum): + ACTIVE = auto() + DISABLED = auto() + DELETED = auto() + +class NodeType(Enum): + TYPE1 = 'Type1' + TYPE2 = 'Type2' + TYPE3 = 'Type3' + +ps_node_table = Table( + 'ps_node', metadata, + Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), + Column('ps_id', Integer, ForeignKey('process_schema.id'), nullable=False), + Column('node_type', SQLAEnum(NodeType), nullable=False), + Column('settings', JSON, default={}), + Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('status', SQLAEnum(NodeStatus), nullable=False), + + Index('idx_ps_id', 'ps_id') +) + +class NodeLinkStatus(str, Enum): + ACTIVE = auto() + STOPPING = auto() + STOPPED = auto() + DELETED = auto() + +node_link_table = Table( + 'node_link', metadata, + Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), + Column('link_name', String(20), nullable=False), + Column('node_id', Integer, ForeignKey('ps_node.id'), nullable=False), + Column('next_node_id', Integer, ForeignKey('ps_node.id'), nullable=False), + Column('settings', JSON, default={}), + Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('created_at', DateTime(timezone=True), server_default=func.now()), + Column('status', SQLAEnum(NodeLinkStatus),nullable=False), + + Index('idx_node_id', 'node_id'), + Index('idx_next_node_id', 'next_node_id')) diff --git a/api/api/schemas/account/__init__.py b/api/api/schemas/account/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/api/schemas/account/account.py b/api/api/schemas/account/account.py new file mode 100644 index 0000000..0abe918 --- /dev/null +++ b/api/api/schemas/account/account.py @@ -0,0 +1,30 @@ +import datetime +from enum import Enum + +from pydantic import BaseModel, EmailStr, Field + + +class Role(Enum): + OWNER = "Owner" + ADMIN = "Admin" + EDITOR = "Editor" + VIEWER = "Viewer" + +class Status(Enum): + ACTIVE = "Active" + DISABLED = "Disabled" + BLOCKED = "Blocked" + DELETED = "Deleted" + +class User(BaseModel): + id: int + name: str = Field(..., max_length=100) + login: str = Field(..., max_length=100) + email: EmailStr = Field(..., max_length=100) + bind_tenant_id: str = Field(..., max_length=40) + role: Role + meta: dict + creator_id: int + is_active: bool + created_at: datetime + status: Status diff --git a/api/api/schemas/account/account_keyring.py b/api/api/schemas/account/account_keyring.py new file mode 100644 index 0000000..8e2a0f0 --- /dev/null +++ b/api/api/schemas/account/account_keyring.py @@ -0,0 +1,27 @@ +import datetime + +from enum import Enum + +from pydantic import BaseModel, Field +from datetime import datetime + + +class Type(Enum): + PASSWORD = "password" + ACCESS_TOKEN = "access_token" + REFRESH_TOKEN = "refresh_token" + API_KEY = "api_key" + +class Status(Enum): + ACTIVE = "Active" + EXPIRED = "Expired" + DELETED = "Deleted" + +class AccountKeyring(BaseModel): + owner_id: int + key_type: Type + key_id: str = Field(..., max_length=40) + key_value: str = Field(..., max_length=64) + created_at: datetime + expiry: datetime + status: Status diff --git a/api/api/schemas/events/__init__.py b/api/api/schemas/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/api/schemas/events/list_events.py b/api/api/schemas/events/list_events.py new file mode 100644 index 0000000..f70ddf5 --- /dev/null +++ b/api/api/schemas/events/list_events.py @@ -0,0 +1,25 @@ +from pydantic import BaseModel, Field +from typing import Dict, Any +from datetime import datetime +from enum import Enum + + +class State(Enum): + AUTO = "Auto" + DESCRIPTED = "Descripted" + + +class Status(Enum): + ACTIVE = "Active" + DISABLED = "Disabled" + DELETED = "Deleted" + +class ListEvent(BaseModel): + id: int + name: str = Field(..., max_length=40) + title: str = Field(..., max_length=64) + creator_id: int + created_at: datetime + schema: Dict[str, Any] + state: State + status: Status diff --git a/api/api/schemas/process/__init__.py b/api/api/schemas/process/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/api/schemas/process/node_link.py b/api/api/schemas/process/node_link.py new file mode 100644 index 0000000..794391d --- /dev/null +++ b/api/api/schemas/process/node_link.py @@ -0,0 +1,20 @@ +from pydantic import BaseModel, Field, conint +from typing import Dict, Any +from datetime import datetime +from enum import Enum + +class Status(Enum): + ACTIVE = "Active" + STOPPING = "Stopping" + STOPPED = "Stopped" + DELETED = "Deleted" + +class MyModel(BaseModel): + id: int + link_name: str = Field(..., max_length=20) + node_id: int + next_node_id: int + settings: Dict[str, Any] + creator_id: int + created_at: datetime + status: Status diff --git a/api/api/schemas/process/process_schema.py b/api/api/schemas/process/process_schema.py new file mode 100644 index 0000000..d4150a4 --- /dev/null +++ b/api/api/schemas/process/process_schema.py @@ -0,0 +1,20 @@ +from pydantic import BaseModel, Field +from typing import Dict, Any +from datetime import datetime +from enum import Enum + +class Status(Enum): + ACTIVE = "Active" + STOPPING = "Stopping" + STOPPED = "Stopped" + DELETED = "Deleted" + +class ProcessSchema(BaseModel): + id: int + title: str = Field(..., max_length=100) + description: str + owner_id: int + creator_id: int + created_at: datetime + settings: Dict[str, Any] + status: Status diff --git a/api/api/schemas/process/process_version_archive.py b/api/api/schemas/process/process_version_archive.py new file mode 100644 index 0000000..556e2ff --- /dev/null +++ b/api/api/schemas/process/process_version_archive.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel, Field +from typing import Dict, Any +from datetime import datetime + +class ProcessStatusSchema(BaseModel): + id: int + version: int + snapshot: Dict[str, Any] + owner_id: int + created_at: datetime + is_last: int diff --git a/api/api/schemas/process/ps_node.py b/api/api/schemas/process/ps_node.py new file mode 100644 index 0000000..e9e6c40 --- /dev/null +++ b/api/api/schemas/process/ps_node.py @@ -0,0 +1,23 @@ +from pydantic import BaseModel +from datetime import datetime +from typing import Dict, Any +from enum import Enum + + +class NodeType(Enum): + + pass + +class Status(Enum): + ACTIVE = "Active" + DISABLED = "Disabled" + DELETED = "Deleted" + +class Ps_Node(BaseModel): + id: int + ps_id: int + node_type: NodeType + settings: dict + creator_id: Dict[str, Any] + created_at: datetime + status: Status -- 2.39.5 From d7bef1ad26290afd83fce096f2765a20240e6f59 Mon Sep 17 00:00:00 2001 From: TheNoxium Date: Mon, 31 Mar 2025 12:34:41 +0500 Subject: [PATCH 2/3] feat: adder unsigned integer for id, function set expiry, "ps_id" --- api/api/db/alembic/env.py | 2 +- api/api/db/sql_types.py | 18 ++++++++++++++++++ api/api/db/tables/account.py | 24 ++++++++++++++++++++---- api/api/db/tables/events.py | 7 +++++-- api/api/db/tables/process.py | 32 ++++++++++++++++++-------------- 5 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 api/api/db/sql_types.py diff --git a/api/api/db/alembic/env.py b/api/api/db/alembic/env.py index 35709fa..190c21d 100644 --- a/api/api/db/alembic/env.py +++ b/api/api/db/alembic/env.py @@ -7,7 +7,7 @@ from sqlalchemy import pool from alembic import context -from api.db import metadata +from api.db import metadata, tables # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/api/api/db/sql_types.py b/api/api/db/sql_types.py new file mode 100644 index 0000000..f988d5a --- /dev/null +++ b/api/api/db/sql_types.py @@ -0,0 +1,18 @@ +__all__ = ["BigIntegerPK", "SAEnum", "UnsignedInt"] + +from typing import Any + +from sqlalchemy import BigInteger, Enum, Integer +from sqlalchemy.dialects import mysql + + +# class SAEnum(Enum): +# def __init__(self, *enums: object, **kw: Any): +# validate_strings = kw.pop("validate_strings", True) +# super().__init__(*enums, **kw, validate_strings=validate_strings) + + +# # https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#allowing-autoincrement-behavior-sqlalchemy-types-other-than-integer-integer + +# BigIntegerPK = BigInteger().with_variant(Integer, "sqlite") +UnsignedInt = Integer().with_variant(mysql.INTEGER(unsigned=True), "mysql") diff --git a/api/api/db/tables/account.py b/api/api/db/tables/account.py index 07ffe3f..46b5e71 100644 --- a/api/api/db/tables/account.py +++ b/api/api/db/tables/account.py @@ -1,6 +1,12 @@ -from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, MetaData +from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index from sqlalchemy.sql import func + +from datetime import datetime, timedelta + from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata @@ -20,14 +26,14 @@ class AccountStatus(str,Enum): account_table = Table( 'account', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('name', String(100), nullable=False), Column('login', String(100), nullable=False), Column('email', String(100), nullable=True), Column('bind_tenant_id', String(40), nullable=True), Column('role', SQLAEnum(AccountRole), nullable=False), Column('meta', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=True), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=True), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(AccountStatus), nullable=False), @@ -48,10 +54,20 @@ class KeyStatus(str,Enum): account_keyring_table = Table( 'account_keyring', metadata, - Column('owner_id', Integer, ForeignKey('account.id'), primary_key=True, nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), primary_key=True, nullable=False), Column('key_type', SQLAEnum(KeyType), primary_key=True, nullable=False), Column('key_id', String(40), default=None), Column('key_value', String(64), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('expiry', DateTime(timezone=True), nullable=True), Column('status', SQLAEnum(KeyStatus), nullable=False), ) + + +def set_expiry_for_key_type(key_type: KeyType) -> datetime: + match key_type: + case KeyType.ACCESS_TOKEN: + return datetime.now() + timedelta(hours=1) # 1 hour + case KeyType.REFRESH_TOKEN: + return datetime.now() + timedelta(days=365) # 1 year + case KeyType.API_KEY: + return datetime.max # max datetime diff --git a/api/api/db/tables/events.py b/api/api/db/tables/events.py index 51179cf..cc33c06 100644 --- a/api/api/db/tables/events.py +++ b/api/api/db/tables/events.py @@ -1,6 +1,9 @@ from sqlalchemy import Table, Column, Integer, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index from sqlalchemy.sql import func from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata class EventState(str, Enum): @@ -15,10 +18,10 @@ class EventStatus(str, Enum): list_events_table = Table( 'list_events', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('name', String(40, collation='latin1_bin'), nullable=False), Column('title', String(64), nullable=False), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('schema', JSON, default={}), Column('state', SQLAEnum(EventState), nullable=False), diff --git a/api/api/db/tables/process.py b/api/api/db/tables/process.py index 0d98353..16bdef3 100644 --- a/api/api/db/tables/process.py +++ b/api/api/db/tables/process.py @@ -1,6 +1,9 @@ from sqlalchemy import Table, Column, Integer, String, Text, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index, PrimaryKeyConstraint from sqlalchemy.sql import func from enum import Enum, auto + +from api.db.sql_types import UnsignedInt + from api.db import metadata @@ -14,11 +17,11 @@ class ProcessStatus(str, Enum): # Определение таблицы process_schema process_schema_table = Table( 'process_schema', metadata, - Column('id', Integer, primary_key=True, autoincrement=True), + Column('id', UnsignedInt, primary_key=True, autoincrement=True), Column('title', String(100), nullable=False), Column('description', Text, nullable=False), - Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('settings', JSON, default={}), Column('status', SQLAEnum(ProcessStatus), nullable=False), @@ -28,12 +31,13 @@ process_schema_table = Table( process_version_archive_table = Table( 'process_version_archive', metadata, - Column('id', Integer, autoincrement=True, nullable=False), - Column('version', Integer, default=1, nullable=False), + Column('id', UnsignedInt, autoincrement=True, nullable=False), + Column('ps_id', UnsignedInt, ForeignKey('process_schema.id'), nullable=False), + Column('version', UnsignedInt, default=1, nullable=False), Column('snapshot', JSON, default={}), - Column('owner_id', Integer, ForeignKey('account.id'), nullable=False), + Column('owner_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), - Column('is_last', Integer, default=0), + Column('is_last', UnsignedInt, default=0), PrimaryKeyConstraint('id', 'version') ) class NodeStatus(str, Enum): @@ -48,11 +52,11 @@ class NodeType(Enum): ps_node_table = Table( 'ps_node', metadata, - Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), - Column('ps_id', Integer, ForeignKey('process_schema.id'), nullable=False), + Column('id', UnsignedInt, autoincrement=True, primary_key=True, nullable=False), + Column('ps_id', UnsignedInt, ForeignKey('process_schema.id'), nullable=False), Column('node_type', SQLAEnum(NodeType), nullable=False), Column('settings', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(NodeStatus), nullable=False), @@ -67,12 +71,12 @@ class NodeLinkStatus(str, Enum): node_link_table = Table( 'node_link', metadata, - Column('id', Integer, autoincrement=True, primary_key=True, nullable=False), + Column('id', UnsignedInt, autoincrement=True, primary_key=True, nullable=False), Column('link_name', String(20), nullable=False), - Column('node_id', Integer, ForeignKey('ps_node.id'), nullable=False), - Column('next_node_id', Integer, ForeignKey('ps_node.id'), nullable=False), + Column('node_id', UnsignedInt, ForeignKey('ps_node.id'), nullable=False), + Column('next_node_id', UnsignedInt, ForeignKey('ps_node.id'), nullable=False), Column('settings', JSON, default={}), - Column('creator_id', Integer, ForeignKey('account.id'), nullable=False), + Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('status', SQLAEnum(NodeLinkStatus),nullable=False), -- 2.39.5 From c9c5837b387c5dd6a583ba94ae225381baefb45a Mon Sep 17 00:00:00 2001 From: TheNoxium Date: Tue, 1 Apr 2025 14:20:40 +0500 Subject: [PATCH 3/3] fix: config, list events table --- api/api/config/default.py | 5 +++-- api/api/db/tables/events.py | 5 +---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/api/config/default.py b/api/api/config/default.py index 3b3b025..392e51f 100644 --- a/api/api/config/default.py +++ b/api/api/config/default.py @@ -1,6 +1,7 @@ import uuid from os import environ +from functools import cached_property from pydantic import BaseModel from pydantic_settings import BaseSettings @@ -43,7 +44,7 @@ class DefaultSettings(BaseSettings): REDIS_DB: int = int(environ.get("REDIS_DB", "0")) REDIS_PASSWORD: str = environ.get("REDIS_PASSWORD", "hackme") - @property + @cached_property def database_settings(self) -> dict: """Get all settings for connection with database.""" return { @@ -54,7 +55,7 @@ class DefaultSettings(BaseSettings): "port": self.MYSQL_PORT, } - @property + @cached_property def database_uri(self) -> str: """Get uri for connection with database.""" uri = "mysql+aiomysql://{user}:{password}@{host}:{port}/{database}".format( diff --git a/api/api/db/tables/events.py b/api/api/db/tables/events.py index cc33c06..eb9c742 100644 --- a/api/api/db/tables/events.py +++ b/api/api/db/tables/events.py @@ -19,14 +19,11 @@ class EventStatus(str, Enum): list_events_table = Table( 'list_events', metadata, Column('id', UnsignedInt, primary_key=True, autoincrement=True), - Column('name', String(40, collation='latin1_bin'), nullable=False), + Column('name', String(40, collation='latin1_bin'), nullable=False,unique=True), Column('title', String(64), nullable=False), Column('creator_id', UnsignedInt, ForeignKey('account.id'), nullable=False), Column('created_at', DateTime(timezone=True), server_default=func.now()), Column('schema', JSON, default={}), Column('state', SQLAEnum(EventState), nullable=False), Column('status', SQLAEnum(EventStatus), nullable=False), - - - Index('UNIQUE_name', 'name', unique=True) ) -- 2.39.5