hdx-python-database 1.3.2__tar.gz → 1.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.config/pre-commit-config.yaml +2 -2
  2. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/PKG-INFO +1 -1
  3. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/pyproject.toml +1 -1
  4. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/requirements.txt +15 -15
  5. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/__init__.py +14 -3
  6. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/_version.py +2 -2
  7. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/postgresql.py +1 -1
  8. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_database.py +9 -15
  9. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_reflect.py +10 -18
  10. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_ssh.py +0 -16
  11. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.config/coveragerc +0 -0
  12. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.config/pytest.ini +0 -0
  13. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.config/ruff.toml +0 -0
  14. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.github/workflows/publish.yaml +0 -0
  15. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.github/workflows/run-python-tests.yaml +0 -0
  16. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/.gitignore +0 -0
  17. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/CONTRIBUTING.md +0 -0
  18. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/LICENSE +0 -0
  19. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/README.md +0 -0
  20. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/documentation/.readthedocs.yaml +0 -0
  21. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/documentation/main.md +0 -0
  22. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/documentation/pydoc-markdown.yaml +0 -0
  23. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/dburi.py +0 -0
  24. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/no_timezone.py +0 -0
  25. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/utils.py +0 -0
  26. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/views.py +0 -0
  27. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/src/hdx/database/with_timezone.py +0 -0
  28. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/fixtures/test.db +0 -0
  29. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/__init__.py +0 -0
  30. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/conftest.py +0 -0
  31. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/dbtestdate.py +0 -0
  32. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_dburi.py +0 -0
  33. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_postgresql.py +0 -0
  34. {hdx_python_database-1.3.2 → hdx_python_database-1.3.4}/tests/hdx/database/test_recreate.py +0 -0
@@ -8,7 +8,7 @@ repos:
8
8
  - id: end-of-file-fixer
9
9
  - id: check-ast
10
10
  - repo: https://github.com/astral-sh/ruff-pre-commit
11
- rev: v0.5.6
11
+ rev: v0.6.9
12
12
  hooks:
13
13
  # Run the linter.
14
14
  - id: ruff
@@ -17,7 +17,7 @@ repos:
17
17
  - id: ruff-format
18
18
  args: [--config, .config/ruff.toml]
19
19
  - repo: https://github.com/astral-sh/uv-pre-commit
20
- rev: 0.2.33
20
+ rev: 0.4.18
21
21
  hooks:
22
22
  # Run the pip compile
23
23
  - id: pip-compile
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-database
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: HDX Python database utilities
5
5
  Project-URL: Homepage, https://github.com/OCHA-DAP/hdx-python-database
6
6
  Author-email: Michael Rans <rans@email.com>
@@ -85,7 +85,7 @@ python = ["3.12"]
85
85
  run = """
86
86
  pytest -c .config/pytest.ini --rootdir=. --junitxml=test-results.xml \
87
87
  --cov --cov-config=.config/coveragerc --no-cov-on-fail \
88
- --cov-report=lcov --cov-report=term-missing -p no:randomly
88
+ --cov-report=lcov --cov-report=term-missing
89
89
  """
90
90
 
91
91
  [tool.hatch.envs.hatch-static-analysis.scripts]
@@ -2,23 +2,23 @@
2
2
  # uv pip compile pyproject.toml --resolver=backtracking --all-extras -o requirements.txt
3
3
  bcrypt==4.2.0
4
4
  # via paramiko
5
- cffi==1.17.0
5
+ cffi==1.17.1
6
6
  # via
7
7
  # cryptography
8
8
  # pynacl
9
9
  cfgv==3.4.0
10
10
  # via pre-commit
11
- coverage==7.6.1
11
+ coverage==7.6.3
12
12
  # via pytest-cov
13
- cryptography==43.0.0
13
+ cryptography==43.0.1
14
14
  # via paramiko
15
- distlib==0.3.8
15
+ distlib==0.3.9
16
16
  # via virtualenv
17
- filelock==3.15.4
17
+ filelock==3.16.1
18
18
  # via virtualenv
19
- greenlet==3.0.3
19
+ greenlet==3.1.1
20
20
  # via sqlalchemy
21
- identify==2.6.0
21
+ identify==2.6.1
22
22
  # via pre-commit
23
23
  iniconfig==2.0.0
24
24
  # via pytest
@@ -26,23 +26,23 @@ nodeenv==1.9.1
26
26
  # via pre-commit
27
27
  packaging==24.1
28
28
  # via pytest
29
- paramiko==3.4.0
29
+ paramiko==3.5.0
30
30
  # via sshtunnel
31
- platformdirs==4.2.2
31
+ platformdirs==4.3.6
32
32
  # via virtualenv
33
33
  pluggy==1.5.0
34
34
  # via pytest
35
- pre-commit==3.8.0
35
+ pre-commit==4.0.1
36
36
  # via hdx-python-database (pyproject.toml)
37
- psycopg==3.2.1
37
+ psycopg==3.2.3
38
38
  # via hdx-python-database (pyproject.toml)
39
- psycopg-binary==3.2.1
39
+ psycopg-binary==3.2.3
40
40
  # via psycopg
41
41
  pycparser==2.22
42
42
  # via cffi
43
43
  pynacl==1.5.0
44
44
  # via paramiko
45
- pytest==8.3.2
45
+ pytest==8.3.3
46
46
  # via
47
47
  # hdx-python-database (pyproject.toml)
48
48
  # pytest-cov
@@ -50,7 +50,7 @@ pytest-cov==5.0.0
50
50
  # via hdx-python-database (pyproject.toml)
51
51
  pyyaml==6.0.2
52
52
  # via pre-commit
53
- sqlalchemy==2.0.32
53
+ sqlalchemy==2.0.35
54
54
  # via hdx-python-database (pyproject.toml)
55
55
  sshtunnel==0.4.0
56
56
  # via hdx-python-database (pyproject.toml)
@@ -58,5 +58,5 @@ typing-extensions==4.12.2
58
58
  # via
59
59
  # psycopg
60
60
  # sqlalchemy
61
- virtualenv==20.26.3
61
+ virtualenv==20.26.6
62
62
  # via pre-commit
@@ -173,7 +173,11 @@ class Database:
173
173
  self.reflected_classes = None
174
174
 
175
175
  def cleanup(self) -> None:
176
- self.base.metadata.clear()
176
+ """Cleanup SQLAlchemy.
177
+
178
+ Returns:
179
+ sqlalchemy.Engine: SQLAlchemy engine
180
+ """
177
181
  self.session.close()
178
182
  self.engine.dispose()
179
183
  if self.server is not None:
@@ -185,7 +189,12 @@ class Database:
185
189
  def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
186
190
  self.cleanup()
187
191
 
188
- def drop_all(self):
192
+ def drop_all(self) -> None:
193
+ """Drop all tables.
194
+
195
+ Returns:
196
+ None
197
+ """
189
198
  self.base.metadata.drop_all(self.engine)
190
199
 
191
200
  def get_engine(self) -> Engine:
@@ -249,7 +258,9 @@ class Database:
249
258
  engine = create_engine(db_uri, poolclass=NullPool, echo=False)
250
259
  if reflect:
251
260
  Base = automap_base(declarative_base=table_base)
252
- Base.prepare(autoload_with=engine)
261
+ Base.prepare(
262
+ autoload_with=engine, reflection_options={"views": True}
263
+ )
253
264
  table_base = Base
254
265
  else:
255
266
  table_base.metadata.create_all(engine)
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.3.2'
16
- __version_tuple__ = version_tuple = (1, 3, 2)
15
+ __version__ = version = '1.3.4'
16
+ __version_tuple__ = version_tuple = (1, 3, 4)
@@ -87,7 +87,7 @@ def restore_from_pgfile(db_uri: str, pg_restore_file: str) -> str:
87
87
  except subprocess.CalledProcessError as ex:
88
88
  command = " ".join(subprocess_params)
89
89
  raise PostgresError(
90
- f"{command} failed. Return code: {process.returncode}"
90
+ f"{command} failed. Return code: {process.returncode}. Error: {process.stderr}"
91
91
  ) from ex
92
92
 
93
93
  for line in process.stdout.splitlines():
@@ -2,7 +2,8 @@
2
2
 
3
3
  from datetime import datetime, timezone
4
4
  from os import remove
5
- from os.path import join
5
+ from os.path import exists, join
6
+ from tempfile import gettempdir
6
7
 
7
8
  import pytest
8
9
  from sqlalchemy import select
@@ -13,30 +14,23 @@ from hdx.database.no_timezone import Base as NoTZBase
13
14
 
14
15
 
15
16
  class TestDatabase:
16
- dbpath = join("tests", "test_database.db")
17
-
18
- @pytest.fixture(scope="function")
19
- def nodatabase(self):
20
- try:
21
- remove(TestDatabase.dbpath)
22
- except OSError:
23
- pass
24
- return f"sqlite:///{TestDatabase.dbpath}"
25
-
26
- def test_get_session(self, nodatabase):
17
+ def test_get_session(self):
27
18
  assert DBTestDate.__tablename__ == "db_test_date"
28
19
 
29
20
  def prepare_fn():
30
21
  return Database.prepare_views([date_view_params])
31
22
 
23
+ dbpath = join(gettempdir(), "test_database.db")
24
+ if exists(dbpath):
25
+ remove(dbpath)
32
26
  with Database(
33
- database=TestDatabase.dbpath,
27
+ database=dbpath,
34
28
  port=None,
35
29
  dialect="sqlite",
36
30
  prepare_fn=prepare_fn,
37
31
  ) as dbdatabase:
38
32
  dbsession = dbdatabase.get_session()
39
- assert str(dbsession.bind.engine.url) == nodatabase
33
+ assert str(dbsession.bind.engine.url) == f"sqlite:///{dbpath}"
40
34
  assert dbdatabase.base == NoTZBase
41
35
  now = datetime(2022, 10, 20, 22, 35, 55, tzinfo=timezone.utc)
42
36
  input_dbtestdate = DBTestDate()
@@ -48,7 +42,7 @@ class TestDatabase:
48
42
  date_view = dbdatabase.get_prepare_results()[0]
49
43
  dbtestdate = dbsession.execute(select(date_view)).scalar_one()
50
44
  assert dbtestdate == now
51
- dbdatabase.drop_all()
45
+ remove(dbpath)
52
46
 
53
47
  def test_errors(self):
54
48
  with pytest.raises(DatabaseError):
@@ -4,8 +4,8 @@ from datetime import datetime
4
4
  from os import remove
5
5
  from os.path import join
6
6
  from shutil import copyfile
7
+ from tempfile import gettempdir
7
8
 
8
- import pytest
9
9
  from sqlalchemy import select
10
10
  from sqlalchemy.orm.decl_api import DeclarativeAttributeIntercept
11
11
 
@@ -13,30 +13,22 @@ from hdx.database import Database
13
13
 
14
14
 
15
15
  class TestReflect:
16
- dbpath = join("tests", "test_database.db")
17
- testdb = join("tests", "fixtures", "test.db")
18
-
19
- @pytest.fixture(scope="function")
20
- def database_to_reflect(self):
21
- try:
22
- remove(TestReflect.dbpath)
23
- copyfile(TestReflect.testdb, TestReflect.dbpath)
24
- except OSError:
25
- pass
26
- return f"sqlite:///{TestReflect.dbpath}"
27
-
28
- def test_get_reflect_session(self, database_to_reflect):
16
+ def test_get_reflect_session(self):
17
+ dbpath = join(gettempdir(), "test_reflect.db")
18
+ testdb = join("tests", "fixtures", "test.db")
19
+ copyfile(testdb, dbpath)
29
20
  with Database(
30
- database=TestReflect.dbpath,
21
+ database=dbpath,
31
22
  port=None,
32
23
  dialect="sqlite",
33
24
  reflect=True,
34
25
  ) as dbdatabase:
35
26
  dbengine = dbdatabase.get_engine()
36
- assert str(dbengine.url) == "sqlite:///tests/test_database.db"
27
+ dburi = f"sqlite:///{dbpath}"
28
+ assert str(dbengine.url) == dburi
37
29
  dbsession = dbdatabase.get_session()
38
30
  assert isinstance(dbdatabase.base, DeclarativeAttributeIntercept)
39
- assert str(dbsession.bind.engine.url) == database_to_reflect
31
+ assert str(dbsession.bind.engine.url) == dburi
40
32
  Table1 = dbdatabase.get_reflected_classes().table1
41
33
  row = dbsession.execute(select(Table1)).scalar_one()
42
34
  assert row.id == "1"
@@ -44,4 +36,4 @@ class TestReflect:
44
36
  # with reflection, type annotation maps do not work and hence
45
37
  # we don't have a timezone here
46
38
  assert row.date1 == datetime(1993, 9, 23, 14, 12, 56, 111000)
47
- dbdatabase.drop_all()
39
+ remove(dbpath)
@@ -34,10 +34,6 @@ class TestSSH:
34
34
  == "postgresql+psycopg://myuser@0.0.0.0:12345/mydatabase"
35
35
  )
36
36
  assert dbdatabase.base == TZBase
37
- try:
38
- dbdatabase.drop_all()
39
- except AttributeError:
40
- pass
41
37
 
42
38
  with Database(
43
39
  ssh_host="mysshhost", ssh_port=25, table_base=TZBase, **params
@@ -48,10 +44,6 @@ class TestSSH:
48
44
  == "postgresql+psycopg://myuser@0.0.0.0:12345/mydatabase"
49
45
  )
50
46
  assert dbdatabase.base == TZBase
51
- try:
52
- dbdatabase.drop_all()
53
- except AttributeError:
54
- pass
55
47
 
56
48
  with Database(ssh_host="mysshhost", **self.params_pg) as dbdatabase:
57
49
  dbsession = dbdatabase.get_session()
@@ -60,10 +52,6 @@ class TestSSH:
60
52
  == "postgresql+psycopg://myuser:***@0.0.0.0:12345/mydatabase"
61
53
  )
62
54
  assert dbdatabase.base == NoTZBase
63
- try:
64
- dbdatabase.drop_all()
65
- except AttributeError:
66
- pass
67
55
 
68
56
  with Database(
69
57
  ssh_host="mysshhost", ssh_port=25, **params
@@ -74,7 +62,3 @@ class TestSSH:
74
62
  == "postgresql+psycopg://myuser@0.0.0.0:12345/mydatabase"
75
63
  )
76
64
  assert dbdatabase.base == NoTZBase
77
- try:
78
- dbdatabase.drop_all()
79
- except AttributeError:
80
- pass