Compare commits
3 commits
706ea80926
...
e38c45b15a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e38c45b15a | ||
![]() |
c9cf13a438 | ||
![]() |
650dc8ff4d |
6 changed files with 31 additions and 8 deletions
|
@ -5,6 +5,12 @@ All notable changes to WuttJamaican will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## v0.21.0 (2025-06-29)
|
||||||
|
|
||||||
|
### Feat
|
||||||
|
|
||||||
|
- remove version cap for SQLAlchemy (allow 1.x or 2.x)
|
||||||
|
|
||||||
## v0.20.6 (2025-06-29)
|
## v0.20.6 (2025-06-29)
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
|
@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "WuttJamaican"
|
name = "WuttJamaican"
|
||||||
version = "0.20.6"
|
version = "0.21.1"
|
||||||
description = "Base package for Wutta Framework"
|
description = "Base package for Wutta Framework"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
||||||
|
@ -38,7 +38,7 @@ dependencies = [
|
||||||
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
db = ["SQLAlchemy<2", "alembic", "alembic-postgresql-enum", "passlib"]
|
db = ["SQLAlchemy", "alembic", "alembic-postgresql-enum", "passlib"]
|
||||||
docs = ["Sphinx", "sphinxcontrib-programoutput", "enum-tools[sphinx]", "furo"]
|
docs = ["Sphinx", "sphinxcontrib-programoutput", "enum-tools[sphinx]", "furo"]
|
||||||
tests = ["pytest-cov", "tox"]
|
tests = ["pytest-cov", "tox"]
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ class DatabaseHandler(GenericHandler):
|
||||||
Base class and default implementation for the :term:`db handler`.
|
Base class and default implementation for the :term:`db handler`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def get_dialect(self, bind):
|
||||||
|
""" """
|
||||||
|
return bind.url.get_dialect().name
|
||||||
|
|
||||||
def next_counter_value(self, session, key):
|
def next_counter_value(self, session, key):
|
||||||
"""
|
"""
|
||||||
Return the next counter value for the given key.
|
Return the next counter value for the given key.
|
||||||
|
@ -52,7 +56,7 @@ class DatabaseHandler(GenericHandler):
|
||||||
|
|
||||||
:returns: Next value as integer.
|
:returns: Next value as integer.
|
||||||
"""
|
"""
|
||||||
dialect = session.bind.url.get_dialect().name
|
dialect = self.get_dialect(session.bind)
|
||||||
|
|
||||||
# postgres uses "true" native sequence
|
# postgres uses "true" native sequence
|
||||||
if dialect == 'postgresql':
|
if dialect == 'postgresql':
|
||||||
|
|
|
@ -25,6 +25,8 @@ Database Utilities
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import uuid as _uuid
|
import uuid as _uuid
|
||||||
|
from importlib.metadata import version
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
@ -44,6 +46,11 @@ naming_convention = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SA2 = True
|
||||||
|
if Version(version('SQLAlchemy')) < Version('2'): # pragma: no cover
|
||||||
|
SA2 = False
|
||||||
|
|
||||||
|
|
||||||
class ModelBase:
|
class ModelBase:
|
||||||
""" """
|
""" """
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,7 @@ else:
|
||||||
# using sqlite backend.
|
# using sqlite backend.
|
||||||
|
|
||||||
# using postgres as backend, should use "sequence"
|
# using postgres as backend, should use "sequence"
|
||||||
with patch.object(self.session.bind.url, 'get_dialect') as get_dialect:
|
with patch.object(handler, 'get_dialect', return_value='postgresql'):
|
||||||
get_dialect.return_value.name = 'postgresql'
|
|
||||||
with patch.object(self.session, 'execute') as execute:
|
with patch.object(self.session, 'execute') as execute:
|
||||||
execute.return_value.scalar.return_value = 1
|
execute.return_value.scalar.return_value = 1
|
||||||
value = handler.next_counter_value(self.session, 'testing')
|
value = handler.next_counter_value(self.session, 'testing')
|
||||||
|
|
|
@ -92,6 +92,8 @@ class TestInstallHandler(ConfigTestCase):
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pytest.skip("test is not relevant without sqlalchemy")
|
pytest.skip("test is not relevant without sqlalchemy")
|
||||||
|
|
||||||
|
from wuttjamaican.db.util import SA2
|
||||||
|
|
||||||
handler = self.make_handler()
|
handler = self.make_handler()
|
||||||
|
|
||||||
def prompt_generic(info, default=None, is_password=False):
|
def prompt_generic(info, default=None, is_password=False):
|
||||||
|
@ -112,6 +114,8 @@ class TestInstallHandler(ConfigTestCase):
|
||||||
self.assertRaises(RuntimeError, handler.get_dbinfo)
|
self.assertRaises(RuntimeError, handler.get_dbinfo)
|
||||||
sys.exit.assert_called_once_with(1)
|
sys.exit.assert_called_once_with(1)
|
||||||
|
|
||||||
|
seekrit = '***' if SA2 else 'seekrit'
|
||||||
|
|
||||||
# good dbinfo
|
# good dbinfo
|
||||||
sys.exit.reset_mock()
|
sys.exit.reset_mock()
|
||||||
test_db_connection.return_value = None
|
test_db_connection.return_value = None
|
||||||
|
@ -119,7 +123,7 @@ class TestInstallHandler(ConfigTestCase):
|
||||||
self.assertFalse(sys.exit.called)
|
self.assertFalse(sys.exit.called)
|
||||||
rprint.assert_called_with("[bold green]good[/bold green]")
|
rprint.assert_called_with("[bold green]good[/bold green]")
|
||||||
self.assertEqual(str(dbinfo['dburl']),
|
self.assertEqual(str(dbinfo['dburl']),
|
||||||
'postgresql+psycopg2://poser:seekrit@localhost:5432/poser')
|
f'postgresql+psycopg2://poser:{seekrit}@localhost:5432/poser')
|
||||||
|
|
||||||
def test_make_db_url(self):
|
def test_make_db_url(self):
|
||||||
try:
|
try:
|
||||||
|
@ -127,13 +131,16 @@ class TestInstallHandler(ConfigTestCase):
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pytest.skip("test is not relevant without sqlalchemy")
|
pytest.skip("test is not relevant without sqlalchemy")
|
||||||
|
|
||||||
|
from wuttjamaican.db.util import SA2
|
||||||
|
|
||||||
handler = self.make_handler()
|
handler = self.make_handler()
|
||||||
|
seekrit = '***' if SA2 else 'seekrit'
|
||||||
|
|
||||||
url = handler.make_db_url('postgresql', 'localhost', '5432', 'poser', 'poser', 'seekrit')
|
url = handler.make_db_url('postgresql', 'localhost', '5432', 'poser', 'poser', 'seekrit')
|
||||||
self.assertEqual(str(url), 'postgresql+psycopg2://poser:seekrit@localhost:5432/poser')
|
self.assertEqual(str(url), f'postgresql+psycopg2://poser:{seekrit}@localhost:5432/poser')
|
||||||
|
|
||||||
url = handler.make_db_url('mysql', 'localhost', '3306', 'poser', 'poser', 'seekrit')
|
url = handler.make_db_url('mysql', 'localhost', '3306', 'poser', 'poser', 'seekrit')
|
||||||
self.assertEqual(str(url), 'mysql+mysqlconnector://poser:seekrit@localhost:3306/poser')
|
self.assertEqual(str(url), f'mysql+mysqlconnector://poser:{seekrit}@localhost:3306/poser')
|
||||||
|
|
||||||
def test_test_db_connection(self):
|
def test_test_db_connection(self):
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue