Ensure one db instance only

Ensure testing db is correctly set to sqlite
This commit is contained in:
Keith Edmunds 2024-06-16 08:40:03 +01:00
parent c0b7bf76f5
commit 71257e4d67
8 changed files with 64 additions and 46 deletions

8
.envrc
View File

@ -4,17 +4,17 @@ export MAIL_PORT=587
export MAIL_SERVER="smtp.fastmail.com"
export MAIL_USERNAME="kae@midnighthax.com"
export MAIL_USE_TLS=True
export PYGAME_HIDE_SUPPORT_PROMPT=1
branch=$(git branch --show-current)
# Always treat running from /home/kae/mm as production
if [ $(pwd) == /home/kae/mm ]; then
export MM_ENV="PRODUCTION"
export ALCHEMICAL_DATABASE_URI="mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_prod"
export DATABASE_URL="mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_prod"
elif on_git_branch master; then
export MM_ENV="PRODUCTION"
export ALCHEMICAL_DATABASE_URI="mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_prod"
export DATABASE_URL="mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_prod"
else
export MM_ENV="DEVELOPMENT"
export ALCHEMICAL_DATABASE_URI="mysql+mysqldb://dev_musicmuster:dev_musicmuster@localhost/dev_musicmuster"
export DATABASE_URL="mysql+mysqldb://dev_musicmuster:dev_musicmuster@localhost/dev_musicmuster"
export PYTHONBREAKPOINT="pudb.set_trace"
fi

30
app/dbmanager.py Normal file
View File

@ -0,0 +1,30 @@
# Standard library imports
# PyQt imports
# Third party imports
from alchemical import Alchemical # type:ignore
# App imports
class DatabaseManager:
"""
Singleton class to ensure we only ever have one db object
"""
__instance = None
def __init__(self, database_url, **kwargs):
if DatabaseManager.__instance is None:
self.db = Alchemical(database_url, **kwargs)
self.db.create_all()
DatabaseManager.__instance = self
else:
raise Exception("Attempted to create a second DatabaseManager instance")
@staticmethod
def get_instance(database_url, **kwargs):
if DatabaseManager.__instance is None:
DatabaseManager(database_url, **kwargs)
return DatabaseManager.__instance

View File

@ -8,7 +8,6 @@ import sys
# PyQt imports
# Third party imports
from alchemical import Alchemical # type:ignore
from sqlalchemy import (
bindparam,
delete,
@ -22,18 +21,20 @@ from sqlalchemy.orm import joinedload
from sqlalchemy.orm.session import Session
# App imports
from dbmanager import DatabaseManager
import dbtables
from config import Config
from log import log
# Establish database connection
ALCHEMICAL_DATABASE_URI = os.environ.get("ALCHEMICAL_DATABASE_URI")
if ALCHEMICAL_DATABASE_URI is None:
raise ValueError("ALCHEMICAL_DATABASE_URI is undefined")
if "unittest" in sys.modules and "sqlite" not in ALCHEMICAL_DATABASE_URI:
DATABASE_URL = os.environ.get("DATABASE_URL")
if DATABASE_URL is None:
raise ValueError("DATABASE_URL is undefined")
if "unittest" in sys.modules and "sqlite" not in DATABASE_URL:
raise ValueError("Unit tests running on non-Sqlite database")
db = Alchemical(ALCHEMICAL_DATABASE_URI, engine_options=Config.ENGINE_OPTIONS)
db = DatabaseManager.get_instance(DATABASE_URL, engine_options=Config.ENGINE_OPTIONS).db
db.create_all()
# Database classes

14
tests/__init__.py Normal file
View File

@ -0,0 +1,14 @@
# Standard library imports
import os
# PyQt imports
# Third party imports
# App imports
# Set up test database before importing db
# https://blog.miguelgrinberg.com/post/how-to-write-unit-tests-in-python-part-3-web-applications
DB_FILE = "/tmp/mm.db"
if os.path.exists(DB_FILE):
os.unlink(DB_FILE)
os.environ["DATABASE_URL"] = "sqlite:///" + DB_FILE

View File

@ -1,5 +1,4 @@
# Standard library imports
import os
import unittest
# PyQt imports
@ -8,15 +7,7 @@ import unittest
import pytest
# App imports
# Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file
# Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = "/tmp/mm.db"
if os.path.exists(DB_FILE):
os.unlink(DB_FILE)
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
from models import db, Settings # noqa: E402
from app.models import db, Settings
class TestMMMisc(unittest.TestCase):

View File

@ -1,6 +1,5 @@
# Standard library imports
import datetime as dt
import os
import unittest
# PyQt imports
@ -10,13 +9,7 @@ import unittest
# App imports
from app import helpers
# Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = "/tmp/mm.db"
if os.path.exists(DB_FILE):
os.unlink(DB_FILE)
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
from app.models import ( # noqa: E402
from app.models import (
db,
NoteColours,
Playdates,

View File

@ -1,5 +1,4 @@
# Standard library imports
import os
import unittest
# PyQt imports
@ -9,15 +8,8 @@ from PyQt6.QtCore import Qt, QModelIndex
# App imports
from app.helpers import get_all_track_metadata
# Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = "/tmp/mm.db"
if os.path.exists(DB_FILE):
os.unlink(DB_FILE)
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
from app import playlistmodel # noqa: E402
from app.models import ( # noqa: E402
from app import playlistmodel
from app.models import (
db,
Playlists,
Tracks,

View File

@ -3,22 +3,19 @@ import os
import unittest
# PyQt imports
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QColor
# Third party imports
import pytest
from pytestqt.plugin import QtBot # type: ignore
# App imports
# Set up test database before importing db
# Mark subsequent lines to ignore E402, imports not at top of file
DB_FILE = "/tmp/mm.db"
if os.path.exists(DB_FILE):
os.unlink(DB_FILE)
os.environ["ALCHEMICAL_DATABASE_URI"] = "sqlite:///" + DB_FILE
from config import Config
from app import playlistmodel, utilities
from app.models import ( # noqa: E402
from app.models import (
db,
NoteColours,
Playlists,
Tracks,
)