hdx-python-database 1.2.8__tar.gz → 1.3.0__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.
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.config/pre-commit-config.yaml +9 -10
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.config/ruff.toml +7 -5
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/CONTRIBUTING.md +2 -3
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/PKG-INFO +1 -1
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/documentation/main.md +13 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/pyproject.toml +4 -12
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/requirements.txt +17 -17
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/__init__.py +8 -5
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/_version.py +2 -2
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/views.py +33 -3
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/dbtestdate.py +8 -6
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/test_database.py +11 -1
- hdx_python_database-1.2.8/.config/black.toml +0 -2
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.config/coveragerc +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.config/pytest.ini +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.github/workflows/publish.yaml +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.github/workflows/run-python-tests.yaml +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.gitignore +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/LICENSE +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/README.md +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/documentation/.readthedocs.yaml +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/documentation/pydoc-markdown.yaml +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/dburi.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/no_timezone.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/postgresql.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/utils.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/src/hdx/database/with_timezone.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/fixtures/test.db +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/__init__.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/conftest.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/test_dburi.py +0 -0
- {hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/test_postgresql.py +0 -0
|
@@ -2,23 +2,22 @@ default_language_version:
|
|
|
2
2
|
python: python3.11
|
|
3
3
|
repos:
|
|
4
4
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
-
rev: v4.
|
|
5
|
+
rev: v4.5.0
|
|
6
6
|
hooks:
|
|
7
7
|
- id: trailing-whitespace
|
|
8
8
|
- id: end-of-file-fixer
|
|
9
9
|
- id: check-ast
|
|
10
|
-
- repo: https://github.com/
|
|
11
|
-
rev:
|
|
12
|
-
hooks:
|
|
13
|
-
- id: black
|
|
14
|
-
args: [--config, .config/black.toml]
|
|
15
|
-
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
|
16
|
-
rev: v0.0.267
|
|
10
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
+
rev: v0.1.14
|
|
17
12
|
hooks:
|
|
13
|
+
# Run the linter.
|
|
18
14
|
- id: ruff
|
|
19
|
-
args: [--config, .config/ruff.toml, --fix
|
|
15
|
+
args: [--config, .config/ruff.toml, --fix]
|
|
16
|
+
# Run the formatter.
|
|
17
|
+
- id: ruff-format
|
|
18
|
+
args: [--config, .config/ruff.toml]
|
|
20
19
|
- repo: https://github.com/jazzband/pip-tools
|
|
21
|
-
rev:
|
|
20
|
+
rev: 7.3.0
|
|
22
21
|
hooks:
|
|
23
22
|
- id: pip-compile
|
|
24
23
|
name: pip-compile requirements.txt
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
line-length = 79
|
|
2
2
|
exclude = ["_version.py"]
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# List of rules: https://beta.ruff.rs/docs/rules/
|
|
3
|
+
|
|
4
|
+
[lint]
|
|
5
|
+
# List of rules: https://docs.astral.sh/ruff/rules/
|
|
7
6
|
select = [
|
|
8
7
|
"E", # pycodestyle - default
|
|
9
8
|
"F", # pyflakes - default
|
|
10
9
|
"I" # isort
|
|
11
10
|
]
|
|
11
|
+
ignore = [
|
|
12
|
+
"E501" # Line too long
|
|
13
|
+
]
|
|
12
14
|
|
|
13
|
-
[isort]
|
|
15
|
+
[lint.isort]
|
|
14
16
|
known-local-folder = ["hdx"]
|
|
@@ -21,14 +21,13 @@ you make a git commit:
|
|
|
21
21
|
pre-commit install
|
|
22
22
|
|
|
23
23
|
The configuration file for this project is in a
|
|
24
|
-
non-
|
|
24
|
+
non-standard location. Thus, you will need to edit your
|
|
25
25
|
`.git/hooks/pre-commit` file to reflect this. Change
|
|
26
26
|
the line that begins with `ARGS` to:
|
|
27
27
|
|
|
28
28
|
ARGS=(hook-impl --config=.config/pre-commit-config.yaml --hook-type=pre-commit)
|
|
29
29
|
|
|
30
30
|
With pre-commit, all code is formatted according to
|
|
31
|
-
[black]("https://github.com/psf/black") and
|
|
32
31
|
[ruff]("https://github.com/charliermarsh/ruff") guidelines.
|
|
33
32
|
|
|
34
33
|
To check if your changes pass pre-commit without committing, run:
|
|
@@ -41,7 +40,7 @@ To run the tests and view coverage, execute:
|
|
|
41
40
|
|
|
42
41
|
pytest -c .config/pytest.ini --cov hdx --cov-config .config/coveragerc
|
|
43
42
|
|
|
44
|
-
Follow the example set out already in ``
|
|
43
|
+
Follow the example set out already in ``documentation/main.md`` as you write the documentation.
|
|
45
44
|
|
|
46
45
|
## Packages
|
|
47
46
|
|
|
@@ -134,6 +134,19 @@ org_type_view = view(
|
|
|
134
134
|
metadata=Base.metadata,
|
|
135
135
|
selectable=select(*DBOrgType.__table__.columns),
|
|
136
136
|
)
|
|
137
|
+
|
|
138
|
+
class DBTestDate(Base):
|
|
139
|
+
test_date: Mapped[datetime] = mapped_column(primary_key=True)
|
|
140
|
+
|
|
141
|
+
date_view_params = {
|
|
142
|
+
"name": "date_view",
|
|
143
|
+
"metadata": Base.metadata,
|
|
144
|
+
"selectable": select(*DBTestDate.__table__.columns),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
date_view = build_view(date_view_params)
|
|
148
|
+
|
|
149
|
+
date_view = build_views([date_view_params])[0]
|
|
137
150
|
```
|
|
138
151
|
|
|
139
152
|
## PostgreSQL specific
|
|
@@ -86,22 +86,14 @@ test = """
|
|
|
86
86
|
"""
|
|
87
87
|
|
|
88
88
|
[[tool.hatch.envs.test.matrix]]
|
|
89
|
-
python = ["3.
|
|
89
|
+
python = ["3.12"]
|
|
90
90
|
|
|
91
91
|
[tool.hatch.envs.lint]
|
|
92
92
|
detached = true
|
|
93
|
-
dependencies = [
|
|
94
|
-
"black",
|
|
95
|
-
"ruff",
|
|
96
|
-
]
|
|
93
|
+
dependencies = ["ruff"]
|
|
97
94
|
|
|
98
95
|
[tool.hatch.envs.lint.scripts]
|
|
99
96
|
style = [
|
|
100
|
-
"ruff --config .config/ruff.toml {args:.}",
|
|
101
|
-
"
|
|
102
|
-
]
|
|
103
|
-
# Not used for anything at the moment
|
|
104
|
-
fmt = [
|
|
105
|
-
"black --config .config/black.toml {args:.}",
|
|
106
|
-
"ruff --config .config/ruff.toml --fix {args:.}",
|
|
97
|
+
"ruff check --config .config/ruff.toml --diff {args:.}",
|
|
98
|
+
"ruff format --config .config/ruff.toml --diff {args:.}",
|
|
107
99
|
]
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#
|
|
5
5
|
# pip-compile --all-extras --output-file=requirements.txt --resolver=backtracking pyproject.toml
|
|
6
6
|
#
|
|
7
|
-
bcrypt==4.
|
|
7
|
+
bcrypt==4.1.2
|
|
8
8
|
# via paramiko
|
|
9
9
|
cffi==1.16.0
|
|
10
10
|
# via
|
|
@@ -12,17 +12,17 @@ cffi==1.16.0
|
|
|
12
12
|
# pynacl
|
|
13
13
|
cfgv==3.4.0
|
|
14
14
|
# via pre-commit
|
|
15
|
-
coverage[toml]==7.
|
|
15
|
+
coverage[toml]==7.4.1
|
|
16
16
|
# via pytest-cov
|
|
17
|
-
cryptography==
|
|
17
|
+
cryptography==42.0.2
|
|
18
18
|
# via paramiko
|
|
19
|
-
distlib==0.3.
|
|
19
|
+
distlib==0.3.8
|
|
20
20
|
# via virtualenv
|
|
21
|
-
filelock==3.
|
|
21
|
+
filelock==3.13.1
|
|
22
22
|
# via virtualenv
|
|
23
|
-
greenlet==3.0.
|
|
23
|
+
greenlet==3.0.3
|
|
24
24
|
# via sqlalchemy
|
|
25
|
-
identify==2.5.
|
|
25
|
+
identify==2.5.34
|
|
26
26
|
# via pre-commit
|
|
27
27
|
iniconfig==2.0.0
|
|
28
28
|
# via pytest
|
|
@@ -30,23 +30,23 @@ nodeenv==1.8.0
|
|
|
30
30
|
# via pre-commit
|
|
31
31
|
packaging==23.2
|
|
32
32
|
# via pytest
|
|
33
|
-
paramiko==3.
|
|
33
|
+
paramiko==3.4.0
|
|
34
34
|
# via sshtunnel
|
|
35
|
-
platformdirs==
|
|
35
|
+
platformdirs==4.2.0
|
|
36
36
|
# via virtualenv
|
|
37
|
-
pluggy==1.
|
|
37
|
+
pluggy==1.4.0
|
|
38
38
|
# via pytest
|
|
39
|
-
pre-commit==3.
|
|
39
|
+
pre-commit==3.6.1
|
|
40
40
|
# via hdx-python-database (pyproject.toml)
|
|
41
|
-
psycopg[binary]==3.1.
|
|
41
|
+
psycopg[binary]==3.1.18
|
|
42
42
|
# via hdx-python-database (pyproject.toml)
|
|
43
|
-
psycopg-binary==3.1.
|
|
43
|
+
psycopg-binary==3.1.18
|
|
44
44
|
# via psycopg
|
|
45
45
|
pycparser==2.21
|
|
46
46
|
# via cffi
|
|
47
47
|
pynacl==1.5.0
|
|
48
48
|
# via paramiko
|
|
49
|
-
pytest==
|
|
49
|
+
pytest==8.0.0
|
|
50
50
|
# via
|
|
51
51
|
# hdx-python-database (pyproject.toml)
|
|
52
52
|
# pytest-cov
|
|
@@ -54,15 +54,15 @@ pytest-cov==4.1.0
|
|
|
54
54
|
# via hdx-python-database (pyproject.toml)
|
|
55
55
|
pyyaml==6.0.1
|
|
56
56
|
# via pre-commit
|
|
57
|
-
sqlalchemy==2.0.
|
|
57
|
+
sqlalchemy==2.0.27
|
|
58
58
|
# via hdx-python-database (pyproject.toml)
|
|
59
59
|
sshtunnel==0.4.0
|
|
60
60
|
# via hdx-python-database (pyproject.toml)
|
|
61
|
-
typing-extensions==4.
|
|
61
|
+
typing-extensions==4.9.0
|
|
62
62
|
# via
|
|
63
63
|
# psycopg
|
|
64
64
|
# sqlalchemy
|
|
65
|
-
virtualenv==20.
|
|
65
|
+
virtualenv==20.25.0
|
|
66
66
|
# via pre-commit
|
|
67
67
|
|
|
68
68
|
# The following packages are considered to be unsafe in a requirements file:
|
|
@@ -23,7 +23,7 @@ class Database:
|
|
|
23
23
|
reflected classes. db_has_tz which defaults to False indicates whether
|
|
24
24
|
database datetime columns have timezones. If not, conversion occurs between
|
|
25
25
|
Python datetimes with timezones to timezoneless database columns (but not
|
|
26
|
-
when using reflection).
|
|
26
|
+
when using reflection). If table_base is supplied, db_has_tz is ignored.
|
|
27
27
|
|
|
28
28
|
Args:
|
|
29
29
|
database (Optional[str]): Database name
|
|
@@ -34,6 +34,7 @@ class Database:
|
|
|
34
34
|
dialect (str): Database dialect. Defaults to "postgresql".
|
|
35
35
|
driver (Optional[str]): Database driver. Defaults to None (psycopg if postgresql or None)
|
|
36
36
|
db_has_tz (bool): True if db datetime columns have timezone. Defaults to False.
|
|
37
|
+
table_base (Optional[Type[DeclarativeBase]]): Override table base. Defaults to None.
|
|
37
38
|
reflect (bool): Whether to reflect existing tables. Defaults to False.
|
|
38
39
|
**kwargs: See below
|
|
39
40
|
ssh_host (str): SSH host (the server to connect to)
|
|
@@ -55,6 +56,7 @@ class Database:
|
|
|
55
56
|
dialect: str = "postgresql",
|
|
56
57
|
driver: Optional[str] = None,
|
|
57
58
|
db_has_tz: bool = False,
|
|
59
|
+
table_base: Optional[Type[DeclarativeBase]] = None,
|
|
58
60
|
reflect: bool = False,
|
|
59
61
|
**kwargs: Any,
|
|
60
62
|
) -> None:
|
|
@@ -98,10 +100,11 @@ class Database:
|
|
|
98
100
|
)
|
|
99
101
|
if dialect == "postgresql":
|
|
100
102
|
wait_for_postgresql(db_uri)
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
if not table_base:
|
|
104
|
+
if db_has_tz:
|
|
105
|
+
table_base = TZBase
|
|
106
|
+
else:
|
|
107
|
+
table_base = NoTZBase
|
|
105
108
|
self.session = self.get_session(
|
|
106
109
|
db_uri, table_base=table_base, reflect=reflect
|
|
107
110
|
)
|
|
@@ -4,8 +4,10 @@ Create a DB View.
|
|
|
4
4
|
Copied from:
|
|
5
5
|
https://github.com/sqlalchemy/sqlalchemy/wiki/Views#sqlalchemy-14-20-version
|
|
6
6
|
"""
|
|
7
|
+
from typing import Dict, List
|
|
8
|
+
|
|
7
9
|
import sqlalchemy as sa
|
|
8
|
-
from sqlalchemy import MetaData,
|
|
10
|
+
from sqlalchemy import MetaData, Selectable, TableClause
|
|
9
11
|
from sqlalchemy.ext import compiler
|
|
10
12
|
from sqlalchemy.schema import DDLElement
|
|
11
13
|
from sqlalchemy.sql import table
|
|
@@ -43,13 +45,13 @@ def view_doesnt_exist(ddl, target, connection, **kw):
|
|
|
43
45
|
return not view_exists(ddl, target, connection, **kw)
|
|
44
46
|
|
|
45
47
|
|
|
46
|
-
def view(name: str, metadata: MetaData, selectable:
|
|
48
|
+
def view(name: str, metadata: MetaData, selectable: Selectable) -> TableClause:
|
|
47
49
|
"""Create SQLAlchemy view
|
|
48
50
|
|
|
49
51
|
Args:
|
|
50
52
|
name (str): View name
|
|
51
53
|
metadata (MetaData): Base metadata
|
|
52
|
-
selectable (
|
|
54
|
+
selectable (Selectable): SQLAlchemy select statement
|
|
53
55
|
|
|
54
56
|
Returns:
|
|
55
57
|
TableClause: SQLAlchemy View
|
|
@@ -71,3 +73,31 @@ def view(name: str, metadata: MetaData, selectable: Select) -> TableClause:
|
|
|
71
73
|
DropView(name).execute_if(callable_=view_exists),
|
|
72
74
|
)
|
|
73
75
|
return t
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def build_view(view_params: Dict) -> TableClause:
|
|
79
|
+
"""Create SQLAlchemy view from dictionary with keys: name, metadata and
|
|
80
|
+
selectable
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
view_params (Dict): Dictionary with keys name, metadata, selectable
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
TableClause: SQLAlchemy View
|
|
87
|
+
"""
|
|
88
|
+
return view(**view_params)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def build_views(view_params_list: List[Dict]) -> List[TableClause]:
|
|
92
|
+
"""Create SQLAlchemy views from a list of dictionaries with keys: name,
|
|
93
|
+
metadata and selectable
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
view_params_list (List[Dict]): List of dictionaries with view parameters
|
|
97
|
+
Returns:
|
|
98
|
+
List[TableClause]: SQLAlchemy Views
|
|
99
|
+
"""
|
|
100
|
+
results = []
|
|
101
|
+
for view_params in view_params_list:
|
|
102
|
+
results.append(build_view(view_params))
|
|
103
|
+
return results
|
|
@@ -6,7 +6,7 @@ from sqlalchemy import select
|
|
|
6
6
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
7
7
|
|
|
8
8
|
from hdx.database.no_timezone import Base
|
|
9
|
-
from hdx.database.views import
|
|
9
|
+
from hdx.database.views import build_views
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class DBTestDate(Base):
|
|
@@ -25,8 +25,10 @@ class DBTestDate(Base):
|
|
|
25
25
|
return f"<Test date={str(self.test_date)}>"
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
name
|
|
30
|
-
metadata
|
|
31
|
-
selectable
|
|
32
|
-
|
|
28
|
+
date_view_params = {
|
|
29
|
+
"name": "date_view",
|
|
30
|
+
"metadata": Base.metadata,
|
|
31
|
+
"selectable": select(*DBTestDate.__table__.columns),
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
date_view = build_views([date_view_params])[0]
|
|
@@ -10,7 +10,7 @@ import pytest
|
|
|
10
10
|
from sqlalchemy import select
|
|
11
11
|
from sshtunnel import SSHTunnelForwarder
|
|
12
12
|
|
|
13
|
-
from .dbtestdate import DBTestDate
|
|
13
|
+
from .dbtestdate import DBTestDate, date_view
|
|
14
14
|
from hdx.database import Database
|
|
15
15
|
from hdx.database.no_timezone import Base as NoTZBase
|
|
16
16
|
from hdx.database.with_timezone import Base as TZBase
|
|
@@ -94,6 +94,8 @@ class TestDatabase:
|
|
|
94
94
|
dbsession.commit()
|
|
95
95
|
dbtestdate = dbsession.execute(select(DBTestDate)).scalar_one()
|
|
96
96
|
assert dbtestdate.test_date == now
|
|
97
|
+
dbtestdate = dbsession.execute(select(date_view)).scalar_one()
|
|
98
|
+
assert dbtestdate == now
|
|
97
99
|
|
|
98
100
|
def test_get_reflect_session(self, database_to_reflect):
|
|
99
101
|
with Database(
|
|
@@ -138,3 +140,11 @@ class TestDatabase:
|
|
|
138
140
|
== "postgresql+psycopg://myuser@0.0.0.0:12345/mydatabase"
|
|
139
141
|
)
|
|
140
142
|
assert TestDatabase.table_base == TZBase
|
|
143
|
+
with Database(
|
|
144
|
+
ssh_host="mysshhost", ssh_port=25, table_base=TZBase, **params
|
|
145
|
+
) as dbsession:
|
|
146
|
+
assert (
|
|
147
|
+
str(dbsession.bind.engine.url)
|
|
148
|
+
== "postgresql+psycopg://myuser@0.0.0.0:12345/mydatabase"
|
|
149
|
+
)
|
|
150
|
+
assert TestDatabase.table_base == TZBase
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/.github/workflows/run-python-tests.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_database-1.2.8 → hdx_python_database-1.3.0}/tests/hdx/database/test_postgresql.py
RENAMED
|
File without changes
|