Initial commit
This commit is contained in:
212
supabase.py
Normal file
212
supabase.py
Normal file
@@ -0,0 +1,212 @@
|
||||
import os
|
||||
from typing import Optional, Dict, List, Any
|
||||
from supabase import create_client, Client
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Загружаем переменные окружения
|
||||
load_dotenv()
|
||||
|
||||
|
||||
class SupabaseManager:
|
||||
"""
|
||||
Класс для управления подключением и операциями с Supabase
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Инициализация подключения к Supabase
|
||||
"""
|
||||
self.url: str = os.getenv("SUPABASE_URL", "")
|
||||
self.key: str = os.getenv("SUPABASE_KEY", "")
|
||||
self.client: Optional[Client] = None
|
||||
|
||||
if not self.url or not self.key:
|
||||
raise ValueError(
|
||||
"SUPABASE_URL и SUPABASE_KEY должны быть установлены в переменных окружения"
|
||||
)
|
||||
|
||||
self._connect()
|
||||
|
||||
def _connect(self) -> None:
|
||||
"""
|
||||
Создает подключение к Supabase
|
||||
"""
|
||||
try:
|
||||
self.client = create_client(self.url, self.key)
|
||||
print("✅ Успешное подключение к Supabase")
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка подключения к Supabase: {e}")
|
||||
raise
|
||||
|
||||
def get_client(self) -> Client:
|
||||
"""
|
||||
Возвращает клиент Supabase
|
||||
|
||||
Returns:
|
||||
Client: Клиент Supabase
|
||||
"""
|
||||
if not self.client:
|
||||
raise ConnectionError("Клиент Supabase не инициализирован")
|
||||
return self.client
|
||||
|
||||
# === Методы для работы с данными ===
|
||||
|
||||
def select(
|
||||
self,
|
||||
table: str,
|
||||
columns: str = "*",
|
||||
filters: Optional[Dict[str, Any]] = None,
|
||||
limit: Optional[int] = None
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
Выполняет SELECT запрос к таблице
|
||||
|
||||
Args:
|
||||
table: Название таблицы
|
||||
columns: Колонки для выборки (по умолчанию все)
|
||||
filters: Словарь с фильтрами {column: value}
|
||||
limit: Лимит количества записей
|
||||
|
||||
Returns:
|
||||
List[Dict]: Список словарей с данными
|
||||
"""
|
||||
try:
|
||||
query = self.client.table(table).select(columns)
|
||||
|
||||
if filters:
|
||||
for column, value in filters.items():
|
||||
query = query.eq(column, value)
|
||||
|
||||
if limit:
|
||||
query = query.limit(limit)
|
||||
|
||||
response = query.execute()
|
||||
return response.data
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при выполнении SELECT: {e}")
|
||||
return []
|
||||
|
||||
def insert(self, table: str, data: Dict[str, Any]) -> Dict:
|
||||
"""
|
||||
Вставляет запись в таблицу
|
||||
|
||||
Args:
|
||||
table: Название таблицы
|
||||
data: Словарь с данными для вставки
|
||||
|
||||
Returns:
|
||||
Dict: Вставленная запись
|
||||
"""
|
||||
try:
|
||||
response = self.client.table(table).insert(data).execute()
|
||||
print(f"✅ Запись успешно добавлена в таблицу {table}")
|
||||
return response.data[0] if response.data else {}
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при вставке данных: {e}")
|
||||
return {}
|
||||
|
||||
def update(
|
||||
self,
|
||||
table: str,
|
||||
data: Dict[str, Any],
|
||||
filters: Dict[str, Any]
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
Обновляет записи в таблице
|
||||
|
||||
Args:
|
||||
table: Название таблицы
|
||||
data: Словарь с данными для обновления
|
||||
filters: Словарь с фильтрами {column: value}
|
||||
|
||||
Returns:
|
||||
List[Dict]: Обновленные записи
|
||||
"""
|
||||
try:
|
||||
query = self.client.table(table).update(data)
|
||||
|
||||
for column, value in filters.items():
|
||||
query = query.eq(column, value)
|
||||
|
||||
response = query.execute()
|
||||
print(f"✅ Записи успешно обновлены в таблице {table}")
|
||||
return response.data
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при обновлении данных: {e}")
|
||||
return []
|
||||
|
||||
def delete(self, table: str, filters: Dict[str, Any]) -> List[Dict]:
|
||||
"""
|
||||
Удаляет записи из таблицы
|
||||
|
||||
Args:
|
||||
table: Название таблицы
|
||||
filters: Словарь с фильтрами {column: value}
|
||||
|
||||
Returns:
|
||||
List[Dict]: Удаленные записи
|
||||
"""
|
||||
try:
|
||||
query = self.client.table(table).delete()
|
||||
|
||||
for column, value in filters.items():
|
||||
query = query.eq(column, value)
|
||||
|
||||
response = query.execute()
|
||||
print(f"✅ Записи успешно удалены из таблицы {table}")
|
||||
return response.data
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при удалении данных: {e}")
|
||||
return []
|
||||
|
||||
# === Методы для работы с Storage ===
|
||||
|
||||
def upload_file(
|
||||
self,
|
||||
bucket: str,
|
||||
file_path: str,
|
||||
file_data: bytes,
|
||||
content_type: Optional[str] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Загружает файл в Storage
|
||||
|
||||
Args:
|
||||
bucket: Название bucket
|
||||
file_path: Путь к файлу в bucket
|
||||
file_data: Данные файла в байтах
|
||||
content_type: MIME тип файла
|
||||
|
||||
Returns:
|
||||
bool: True если загрузка успешна
|
||||
"""
|
||||
try:
|
||||
options = {"content-type": content_type} if content_type else {}
|
||||
self.client.storage.from_(bucket).upload(
|
||||
file_path,
|
||||
file_data,
|
||||
file_options=options
|
||||
)
|
||||
print(f"✅ Файл {file_path} успешно загружен в bucket {bucket}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при загрузке файла: {e}")
|
||||
return False
|
||||
|
||||
def get_public_url(self, bucket: str, file_path: str) -> str:
|
||||
"""
|
||||
Получает публичный URL файла
|
||||
|
||||
Args:
|
||||
bucket: Название bucket
|
||||
file_path: Путь к файлу в bucket
|
||||
|
||||
Returns:
|
||||
str: Публичный URL
|
||||
"""
|
||||
try:
|
||||
url = self.client.storage.from_(bucket).get_public_url(file_path)
|
||||
return url
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при получении URL: {e}")
|
||||
return ""
|
||||
Reference in New Issue
Block a user