Добавил проект с учетом .gitignore

This commit is contained in:
2025-07-06 19:24:54 +03:00
parent 41ad5a5b92
commit e796892942
20 changed files with 6162 additions and 3 deletions

View File

@@ -0,0 +1,128 @@
import disnake
from disnake.ext import commands
from disnake.ext import tasks
from typing import Optional, Union, List, Dict, Any, AsyncIterator, Tuple
import datetime
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import joinedload, selectinload, contains_eager
from sqlalchemy import select, delete, insert, update, func, asc, desc
from sqlalchemy import and_, or_, not_
import subprocess
import os
from types import SimpleNamespace
class Model:
def __init__(self, model):
self.model = model
self.m = model
async def __aenter__(self):
return self.model
async def __aexit__(self, exc_type, exc_val, exc_tb):
return None
class DatabaseManager:
def __init__(self, engine, tables_data):
self.engine = engine
self.session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
self.metadata = tables_data['base'].metadata
self.model_classes = {}
tables = self.metadata.tables
for table_name, table in tables.items():
model_class = next((cls for cls in tables_data['base'].__subclasses__() if cls.__tablename__ == table_name), None)
if model_class:
#print(f"Table: {table_name}, Model Class: {model_class.__name__}")
self.model_classes[table_name] = model_class
self.models = {table_name: Model(model) for table_name, model in self.model_classes.items()}
self.tables_data = tables_data
#функции sqlalchemy
self.joinedload = joinedload
self.selectinload = selectinload
self.contains_eager = contains_eager
self.select = select
self.delete = delete
self.insert = insert
self.update = update
self.func = func
self.desc = desc
self.asc = asc
self.and_ = and_
self.or_ = or_
self.not_ = not_
#ошибки sqlalchemy
exceptions = SimpleNamespace(
IntegrityError = IntegrityError
)
async def close(self):
await self.engine.dispose()
async def pg_dump(self, echo=False, backup_file='src/backups/discord_economy_bot_backup.sql'):
conn = await self.engine.connect()
db_name = self.engine.url.database
user = self.engine.url.username
host = self.engine.url.host
port = self.engine.url.port
password = self.engine.url.password
os.environ['PGPASSWORD'] = password
command = [
'pg_dump',
'-h', host,
'-p', str(port),
'-U', user,
'-F', 'p', # <-- plain text SQL
] + (['-v'] if echo else []) + [
'-f', backup_file,
db_name
]
try:
subprocess.run(command, check=True)
if echo:
print(f"{datetime.datetime.now():%H:%M:%S %d-%m-%Y} :: SQL backup of '{db_name}' created.")
return backup_file
except subprocess.CalledProcessError as e:
print(f"{datetime.datetime.now():%H:%M:%S %d-%m-%Y} :: Backup failed: {e}")
return f"{datetime.datetime.now():%H:%M:%S %d-%m-%Y} :: Backup failed: {e}"
finally:
await conn.close()
async def pg_restore(self, echo = False, backup_file = 'src/backups/backup_file.backup'):
conn = await self.DataBaseManager.engine.connect()
db_name = self.DataBaseManager.engine.url.database
user = self.DataBaseManager.engine.url.username
host = self.DataBaseManager.engine.url.host
port = self.DataBaseManager.engine.url.port
password = self.DataBaseManager.engine.url.password
os.environ['PGPASSWORD'] = password # Установка пароля для подключения
command = [
'pg_restore',
'-h', host,
'-p', str(port),
'-U', user,
'-d', db_name, # Имя базы данных, в которую будет восстановлено
] + ([
'-v' # Подробный вывод
] if echo else []) + [
backup_file # Путь к файлу резервной копии
]
try:
subprocess.run(command, check=True)
if echo:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Database '{db_name}' restored successfully from '{backup_file}'.")
except subprocess.CalledProcessError as e:
print(f"{datetime.datetime.now().strftime('%H:%M:%S %d-%m-%Y')}:: Error during restore: {e}")
finally:
await conn.close()