feat: added sql tables and db connection
This commit is contained in:
parent
49be3c376c
commit
b95b7caefd
@ -43,6 +43,26 @@ class DefaultSettings(BaseSettings):
|
|||||||
REDIS_DB: int = int(environ.get("REDIS_DB", "0"))
|
REDIS_DB: int = int(environ.get("REDIS_DB", "0"))
|
||||||
REDIS_PASSWORD: str = environ.get("REDIS_PASSWORD", "hackme")
|
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:
|
class Config:
|
||||||
# env_file = "../.env"
|
# env_file = "../.env"
|
||||||
env_file_encoding = "utf-8"
|
env_file_encoding = "utf-8"
|
||||||
|
63
api/api/db/connection/session.py
Normal file
63
api/api/db/connection/session.py
Normal file
@ -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
|
@ -0,0 +1 @@
|
|||||||
|
from . import account,events,process
|
57
api/api/db/tables/account.py
Normal file
57
api/api/db/tables/account.py
Normal file
@ -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), )
|
29
api/api/db/tables/events.py
Normal file
29
api/api/db/tables/events.py
Normal file
@ -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)
|
||||||
|
)
|
80
api/api/db/tables/process.py
Normal file
80
api/api/db/tables/process.py
Normal file
@ -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'))
|
0
api/api/schemas/account/__init__.py
Normal file
0
api/api/schemas/account/__init__.py
Normal file
30
api/api/schemas/account/account.py
Normal file
30
api/api/schemas/account/account.py
Normal file
@ -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
|
27
api/api/schemas/account/account_keyring.py
Normal file
27
api/api/schemas/account/account_keyring.py
Normal file
@ -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
|
0
api/api/schemas/events/__init__.py
Normal file
0
api/api/schemas/events/__init__.py
Normal file
25
api/api/schemas/events/list_events.py
Normal file
25
api/api/schemas/events/list_events.py
Normal file
@ -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
|
0
api/api/schemas/process/__init__.py
Normal file
0
api/api/schemas/process/__init__.py
Normal file
20
api/api/schemas/process/node_link.py
Normal file
20
api/api/schemas/process/node_link.py
Normal file
@ -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
|
20
api/api/schemas/process/process_schema.py
Normal file
20
api/api/schemas/process/process_schema.py
Normal file
@ -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
|
11
api/api/schemas/process/process_version_archive.py
Normal file
11
api/api/schemas/process/process_version_archive.py
Normal file
@ -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
|
23
api/api/schemas/process/ps_node.py
Normal file
23
api/api/schemas/process/ps_node.py
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user