Skip to content

Add black formatter #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
"."
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
"python.testing.pytestEnabled": true,
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
2 changes: 1 addition & 1 deletion database_setup_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__='1.0.1'
__version__ = "1.0.1"

from .session_manager import SessionManager
from .setup import DatabaseSetup
15 changes: 8 additions & 7 deletions database_setup_tools/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@


class SessionManager:
""" Manages engines, sessions and connection pools. Thread-safe singleton """
"""Manages engines, sessions and connection pools. Thread-safe singleton"""

_instances = []
_lock = threading.Lock()

Expand All @@ -21,7 +22,7 @@ def __new__(cls, *args, **kwargs):
return cls._get_cached_instance(args, kwargs)

def __init__(self, database_uri: str, **kwargs):
""" Session Manager constructor
"""Session Manager constructor

Args:
database_uri (str): The URI of the database to manage sessions for
Expand All @@ -44,26 +45,26 @@ def __init__(self, database_uri: str, **kwargs):

@cached_property
def database_uri(self) -> str:
""" Getter for the database URI """
"""Getter for the database URI"""
return self._database_uri

@property
def engine(self) -> Engine:
""" Getter for the engine """
"""Getter for the engine"""
return self._engine

def get_session(self) -> Generator[Session, None, None]:
""" Provides a (thread safe) scoped session that is wrapped in a context manager """
"""Provides a (thread safe) scoped session that is wrapped in a context manager"""
with self._Session() as session:
yield session

def _get_engine(self, **kwargs) -> Engine:
""" Provides a database engine """
"""Provides a database engine"""
return create_engine(self.database_uri, **kwargs)

@classmethod
def _get_cached_instance(cls, args: tuple, kwargs: dict) -> Optional[object]:
""" Provides a cached instance of the SessionManager class if existing """
"""Provides a cached instance of the SessionManager class if existing"""
for instance, arguments in cls._instances:
if arguments == (args, kwargs):
return instance
Expand Down
15 changes: 8 additions & 7 deletions database_setup_tools/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@


class DatabaseSetup:
""" Create the database and the tables if not done yet """
"""Create the database and the tables if not done yet"""

_instances = []
_lock = threading.Lock()

Expand All @@ -20,7 +21,7 @@ def __new__(cls, *args, **kwargs):
return cls._get_cached_instance(args, kwargs)

def __init__(self, model_metadata: MetaData, database_uri: str):
""" Set up a database based on its URI and metadata. Will not overwrite existing data.
"""Set up a database based on its URI and metadata. Will not overwrite existing data.

Args:
model_metadata (Metadata): The metadata of the models to create the tables for
Expand All @@ -39,7 +40,7 @@ def __init__(self, model_metadata: MetaData, database_uri: str):

@property
def model_metadata(self) -> MetaData:
""" Getter for the model metadata
"""Getter for the model metadata

Returns:
MetaData: The model metadata
Expand All @@ -48,15 +49,15 @@ def model_metadata(self) -> MetaData:

@property
def database_uri(self) -> str:
""" Getter for the database URI
"""Getter for the database URI

Returns:
str: The database URI
"""
return self._database_uri

def drop_database(self) -> bool:
""" Drop the database and the tables if possible
"""Drop the database and the tables if possible

Returns:
bool: True if the database was dropped, False otherwise
Expand All @@ -67,7 +68,7 @@ def drop_database(self) -> bool:
return False

def create_database(self) -> bool:
""" Create the database and the tables if not done yet """
"""Create the database and the tables if not done yet"""
if not sqlalchemy_utils.database_exists(self.database_uri):
sqlalchemy_utils.create_database(self.database_uri)
session_manager = SessionManager(self.database_uri)
Expand All @@ -77,7 +78,7 @@ def create_database(self) -> bool:

@classmethod
def _get_cached_instance(cls, args: tuple, kwargs: dict) -> Optional[object]:
""" Provides a cached instance of the SessionManager class if existing """
"""Provides a cached instance of the SessionManager class if existing"""
for instance, arguments in cls._instances:
if arguments == (args, kwargs):
return instance
Expand Down
107 changes: 106 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ sqlalchemy = "^1.4.41"
sqlalchemy-utils = "^0.38.3"

[tool.poetry.dev-dependencies]
black = "23.1.0"
sqlmodel = "0.0.8"
psycopg2-binary = "^2.9.5"
pytest-cov = "^4.0.0"
Expand All @@ -27,3 +28,7 @@ build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
addopts = "-x -p no:warnings --cov-report=term --cov-report=term-missing --no-cov-on-fail --cov=database_setup_tools"

[tool.black]
line-length = 180
target-version = ['py311']
17 changes: 8 additions & 9 deletions tests/integration/test_database_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
from tests.sample_model import User, model_metadata


@pytest.mark.parametrize('database_uri', DATABASE_URIS)
@pytest.mark.parametrize("database_uri", DATABASE_URIS)
class TestDatabaseIntegration:

@pytest.fixture
def database_setup(self, database_uri: str) -> DatabaseSetup:
setup = DatabaseSetup(model_metadata=model_metadata, database_uri=database_uri)
Expand All @@ -21,28 +20,28 @@ def database_setup(self, database_uri: str) -> DatabaseSetup:

@pytest.fixture
def database_session(self, database_uri: str) -> Iterator[ScopedSession]:
""" Get a database session """
"""Get a database session"""
session_manager = SessionManager(database_uri)
return next(session_manager.get_session())

def test_create_database_and_tables(self, database_setup: DatabaseSetup, database_session: ScopedSession):
""" Test that the tables are created correctly """
"""Test that the tables are created correctly"""
# noinspection SqlInjection,SqlDialectInspection
database_session.execute(f'SELECT * FROM {User.__tablename__}')
database_session.execute(f"SELECT * FROM {User.__tablename__}")

def test_create_database_multiple_times(self, database_setup: DatabaseSetup, database_session: ScopedSession):
""" Test that creating the database multiple times does not cause problems """
"""Test that creating the database multiple times does not cause problems"""
database_setup.create_database()
# noinspection SqlInjection,SqlDialectInspection
database_session.execute(f'SELECT * FROM {User.__tablename__}')
database_session.execute(f"SELECT * FROM {User.__tablename__}")

def test_drop_database(self, database_setup: DatabaseSetup, database_session: ScopedSession):
""" Test that the database is dropped correctly """
"""Test that the database is dropped correctly"""
database_setup.create_database()
assert database_setup.drop_database() is True

with pytest.raises(OperationalError):
# noinspection SqlDialectInspection
database_session.execute(f'SELECT * FROM {User.__tablename__}')
database_session.execute(f"SELECT * FROM {User.__tablename__}")

assert database_setup.drop_database() is False
2 changes: 1 addition & 1 deletion tests/sample_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


class User(SQLModel, table=True):
""" User model """
"""User model"""

id: int = Field(index=True, primary_key=True)
name: str
Expand Down
12 changes: 4 additions & 8 deletions tests/unit/test_session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@


class TestSessionManager:

@pytest.fixture
def database_uri(self) -> str:
return 'sqlite://'
return "sqlite://"

@pytest.fixture
def session_manager(self, database_uri: str) -> SessionManager:
yield SessionManager(database_uri=database_uri)

@pytest.mark.parametrize('invalid_database_uri', [None, (), 42, False])
@pytest.mark.parametrize("invalid_database_uri", [None, (), 42, False])
def test_create_session_manager_fail_invalid_database_uri_type(self, invalid_database_uri: Any):
with pytest.raises(TypeError):
SessionManager(database_uri=invalid_database_uri)
Expand All @@ -27,16 +26,13 @@ def test_session_manager_is_singleton_with_same_arguments(self, database_uri: st
assert SessionManager(database_uri=database_uri) is SessionManager(database_uri=database_uri)

def test_session_manager_singletons_with_different_arguments(self):
database_uri_1, database_uri_2 = 'sqlite://', 'postgresql://'
database_uri_1, database_uri_2 = "sqlite://", "postgresql://"
assert SessionManager(database_uri=database_uri_1) is not SessionManager(database_uri=database_uri_2)

def test_database_uri(self, session_manager: SessionManager, database_uri: str):
assert session_manager.database_uri == database_uri

@pytest.mark.parametrize('database_uri, name, driver', [
('sqlite://', 'sqlite', 'pysqlite'),
('postgresql+psycopg2://', 'postgresql', 'psycopg2')
])
@pytest.mark.parametrize("database_uri, name, driver", [("sqlite://", "sqlite", "pysqlite"), ("postgresql+psycopg2://", "postgresql", "psycopg2")])
def test_engine(self, database_uri: str, name: str, driver: str):
session_manager = SessionManager(database_uri)
assert isinstance(session_manager.engine, Engine)
Expand Down
Loading