tabletop-frog/ttfrog/db/manager.py

89 lines
2.3 KiB
Python
Raw Normal View History

2024-01-30 01:25:02 -08:00
import transaction
2024-01-28 22:14:50 -08:00
import base64
import hashlib
2024-01-28 14:31:50 -08:00
import logging
2024-01-28 00:46:19 -08:00
2024-01-28 22:14:50 -08:00
from functools import cached_property
2024-01-30 01:25:02 -08:00
from pyramid_sqlalchemy import Session
from pyramid_sqlalchemy import init_sqlalchemy
from pyramid_sqlalchemy import metadata as _metadata
2024-01-28 00:46:19 -08:00
from sqlalchemy import create_engine
2024-01-28 22:14:50 -08:00
from sqlalchemy.exc import IntegrityError
2024-01-28 00:46:19 -08:00
from ttfrog.path import database
2024-01-30 01:25:02 -08:00
import ttfrog.db.schema
ttfrog.db.schema
2024-01-28 00:46:19 -08:00
class SQLDatabaseManager:
"""
A context manager for working with sqllite database.
"""
@cached_property
def url(self):
return f"sqlite:///{database()}"
@cached_property
def engine(self):
2024-01-30 01:25:02 -08:00
return create_engine(self.url)
@cached_property
def session(self):
return Session
2024-01-28 00:46:19 -08:00
@cached_property
2024-01-30 01:25:02 -08:00
def metadata(self):
return _metadata
2024-01-28 00:46:19 -08:00
@cached_property
def tables(self):
2024-01-30 01:25:02 -08:00
return dict((t.name, t) for t in self.metadata.sorted_tables)
2024-01-28 00:46:19 -08:00
def query(self, *args, **kwargs):
2024-01-30 01:25:02 -08:00
return self.session.query(*args, **kwargs)
2024-01-28 00:46:19 -08:00
2024-01-28 22:14:50 -08:00
def execute(self, statement) -> tuple:
2024-01-30 01:25:02 -08:00
logging.info(statement)
2024-01-28 22:14:50 -08:00
result = None
error = None
try:
2024-01-30 01:25:02 -08:00
with transaction.manager as tx:
result = self.session.execute(statement)
tx.commit()
2024-01-28 22:14:50 -08:00
except IntegrityError as exc:
logging.error(exc)
2024-01-30 01:25:02 -08:00
error = "I AM ERROR."
2024-01-28 22:14:50 -08:00
return result, error
def insert(self, table, **kwargs) -> tuple:
stmt = table.insert().values(**kwargs)
return self.execute(stmt)
2024-01-28 14:31:50 -08:00
def update(self, table, **kwargs):
2024-01-28 22:14:50 -08:00
primary_key = kwargs.pop('id')
stmt = table.update().values(**kwargs).where(table.columns.id == primary_key)
return self.execute(stmt)
2024-01-28 14:31:50 -08:00
2024-01-28 22:14:50 -08:00
def slugify(self, rec: dict) -> str:
"""
Create a uniquish slug from a dictionary.
"""
sha1bytes = hashlib.sha1(str(rec['id']).encode())
return base64.urlsafe_b64encode(sha1bytes.digest()).decode("ascii")[:10]
2024-01-30 01:25:02 -08:00
def init(self):
init_sqlalchemy(self.engine)
self.metadata.create_all(self.engine)
2024-01-28 22:14:50 -08:00
2024-01-28 00:46:19 -08:00
def __getattr__(self, name: str):
try:
return self.tables[name]
except KeyError:
raise AttributeError(f"{self} does not contain the attribute '{name}'.")
db = SQLDatabaseManager()