sqlalchemy-multiple-db 2.1.0__tar.gz → 3.0.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.
- sqlalchemy_multiple_db-3.0.0/.github/SECURITY.md +8 -0
- sqlalchemy_multiple_db-3.0.0/.github/dependabot.yml +10 -0
- sqlalchemy_multiple_db-3.0.0/.github/workflows/ci.yml +36 -0
- sqlalchemy_multiple_db-3.0.0/.github/workflows/publish.yml +41 -0
- sqlalchemy_multiple_db-3.0.0/.gitignore +77 -0
- sqlalchemy_multiple_db-3.0.0/CHANGELOG.md +112 -0
- sqlalchemy_multiple_db-3.0.0/Makefile +178 -0
- sqlalchemy_multiple_db-3.0.0/PKG-INFO +123 -0
- sqlalchemy_multiple_db-3.0.0/README.md +98 -0
- sqlalchemy_multiple_db-3.0.0/examples/basic_usage.py +38 -0
- sqlalchemy_multiple_db-3.0.0/examples/healthcheck_and_options.py +39 -0
- sqlalchemy_multiple_db-3.0.0/examples/transaction_rollback.py +35 -0
- sqlalchemy_multiple_db-3.0.0/pyproject.toml +61 -0
- sqlalchemy_multiple_db-3.0.0/src/sqlalchemy_multiple_db/__init__.py +14 -0
- sqlalchemy_multiple_db-3.0.0/src/sqlalchemy_multiple_db/config.py +28 -0
- sqlalchemy_multiple_db-3.0.0/src/sqlalchemy_multiple_db/exceptions.py +6 -0
- sqlalchemy_multiple_db-3.0.0/src/sqlalchemy_multiple_db/manager.py +110 -0
- sqlalchemy_multiple_db-3.0.0/tests/test_config.py +44 -0
- sqlalchemy_multiple_db-3.0.0/tests/test_examples.py +29 -0
- sqlalchemy_multiple_db-3.0.0/tests/test_manager.py +144 -0
- sqlalchemy_multiple_db-3.0.0/tests/test_public_api.py +15 -0
- sqlalchemy_multiple_db-3.0.0/uv.lock +597 -0
- sqlalchemy-multiple-db-2.1.0/MANIFEST.in +0 -6
- sqlalchemy-multiple-db-2.1.0/PKG-INFO +0 -81
- sqlalchemy-multiple-db-2.1.0/README.md +0 -51
- sqlalchemy-multiple-db-2.1.0/pyproject.toml +0 -18
- sqlalchemy-multiple-db-2.1.0/setup.cfg +0 -4
- sqlalchemy-multiple-db-2.1.0/setup.py +0 -54
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db/__init__.py +0 -3
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db/helper.py +0 -107
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db/version.py +0 -3
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/PKG-INFO +0 -81
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/SOURCES.txt +0 -14
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/dependency_links.txt +0 -1
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/not-zip-safe +0 -1
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/requires.txt +0 -1
- sqlalchemy-multiple-db-2.1.0/sqlalchemy_multiple_db.egg-info/top_level.txt +0 -2
- {sqlalchemy-multiple-db-2.1.0 → sqlalchemy_multiple_db-3.0.0}/LICENSE +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
quality:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.14"
|
|
17
|
+
- uses: astral-sh/setup-uv@v7
|
|
18
|
+
- run: uv sync --all-groups --locked
|
|
19
|
+
- run: uv run ruff format --check src tests
|
|
20
|
+
- run: uv run ruff check src tests
|
|
21
|
+
- run: uv run mypy src
|
|
22
|
+
|
|
23
|
+
test:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
strategy:
|
|
26
|
+
fail-fast: false
|
|
27
|
+
matrix:
|
|
28
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
- uses: astral-sh/setup-uv@v7
|
|
35
|
+
- run: uv sync --all-groups --locked
|
|
36
|
+
- run: uv run pytest --cov=sqlalchemy_multiple_db --cov-report=term-missing
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-python@v5
|
|
13
|
+
with:
|
|
14
|
+
python-version: "3.14"
|
|
15
|
+
- uses: astral-sh/setup-uv@v7
|
|
16
|
+
- run: uv sync --all-groups --locked
|
|
17
|
+
- run: uv run ruff format --check src tests
|
|
18
|
+
- run: uv run ruff check src tests
|
|
19
|
+
- run: uv run mypy src
|
|
20
|
+
- run: uv run pytest
|
|
21
|
+
- run: uv build
|
|
22
|
+
- run: uv run python -m zipfile -t dist/*.whl
|
|
23
|
+
- uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: python-package-distributions
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish-to-pypi:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment:
|
|
32
|
+
name: pypi
|
|
33
|
+
url: https://pypi.org/p/sqlalchemy-multiple-db
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: python-package-distributions
|
|
40
|
+
path: dist/
|
|
41
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
.idea
|
|
6
|
+
media
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
env/
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
|
|
27
|
+
configs/local_settings.py
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
|
|
50
|
+
# Translations
|
|
51
|
+
*.pot
|
|
52
|
+
|
|
53
|
+
# Django stuff:
|
|
54
|
+
*.log
|
|
55
|
+
|
|
56
|
+
# Sphinx documentation
|
|
57
|
+
docs/_build/
|
|
58
|
+
|
|
59
|
+
# PyBuilder
|
|
60
|
+
target/
|
|
61
|
+
|
|
62
|
+
#Ipython Notebook
|
|
63
|
+
.ipynb_checkpoints
|
|
64
|
+
venv/*
|
|
65
|
+
env/*
|
|
66
|
+
.venv/
|
|
67
|
+
.env/*
|
|
68
|
+
.uv/
|
|
69
|
+
.mypy_cache/
|
|
70
|
+
.pytest_cache/
|
|
71
|
+
.ruff_cache/
|
|
72
|
+
|
|
73
|
+
address.txt
|
|
74
|
+
private_keys.txt
|
|
75
|
+
|
|
76
|
+
# Idea modules
|
|
77
|
+
*.iml
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
|
|
2
|
+
# Changelog
|
|
3
|
+
|
|
4
|
+
## 3.0.0 (Unreleased)
|
|
5
|
+
|
|
6
|
+
### Breaking changes
|
|
7
|
+
|
|
8
|
+
- Dropped Python 3.7–3.10; supported versions are Python 3.11–3.14.
|
|
9
|
+
- Dropped SQLAlchemy 1.x and require SQLAlchemy 2.x.
|
|
10
|
+
- Replaced `DBConfig`, `DBHelper`, global `db`, `setup`, `session_scope`, `get_status_info`, and `shutdown` with `DatabaseConfig` and explicit `DatabaseManager` lifecycle methods.
|
|
11
|
+
- Removed the implicit default database and `scoped_session` usage.
|
|
12
|
+
- Moved packaging and dependency management to uv, `pyproject.toml`, and `uv.lock`.
|
|
13
|
+
|
|
14
|
+
## 2.1.0 (2024-10-18)
|
|
15
|
+
|
|
16
|
+
* Update pipeline [Pavel Liashkov]
|
|
17
|
+
* Update version [Pavel Liashkov]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## 2.0.0 (2023-08-03)
|
|
21
|
+
|
|
22
|
+
* Update sqlalchemy requirement from <1.5,>=1.4 to >=1.4,<2.1 [dependabot[bot]]
|
|
23
|
+
* Fix pipeline (#27) [Pavel Liashkov]
|
|
24
|
+
* Update version [Pavel Liashkov]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## 1.8.0 (2021-07-26)
|
|
28
|
+
|
|
29
|
+
* Relax reqs version [Pavel Liashkov]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## 1.7.0 (2021-07-23)
|
|
33
|
+
|
|
34
|
+
* Bump sqlalchemy from 1.4.18 to 1.4.19 [dependabot[bot]]
|
|
35
|
+
* Bump sqlalchemy from 1.4.19 to 1.4.20 [dependabot[bot]]
|
|
36
|
+
* Bump sqlalchemy from 1.4.20 to 1.4.22 [dependabot[bot]]
|
|
37
|
+
* Update version.py [Pavel Liashkov]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## 1.6.0 (2021-06-18)
|
|
41
|
+
|
|
42
|
+
* Bump sqlalchemy from 1.4.17 to 1.4.18 [dependabot[bot]]
|
|
43
|
+
* Update version.py [Pavel Liashkov]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## 1.5.0 (2021-06-04)
|
|
47
|
+
|
|
48
|
+
* Bump sqlalchemy from 1.4.15 to 1.4.17 [dependabot[bot]]
|
|
49
|
+
* Update version.py [Pavel Liashkov]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## 1.4.0 (2021-05-18)
|
|
53
|
+
|
|
54
|
+
* Bump sqlalchemy from 1.4.13 to 1.4.15 [dependabot[bot]]
|
|
55
|
+
* Update version.py [Pavel Liashkov]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## 1.3.0 (2021-05-05)
|
|
59
|
+
|
|
60
|
+
* Bump sqlalchemy from 1.4.8 to 1.4.13 [dependabot[bot]]
|
|
61
|
+
* Update version.py [Pavel Liashkov]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## 1.2.0 (2021-04-16)
|
|
65
|
+
|
|
66
|
+
* Bump sqlalchemy from 1.4.5 to 1.4.8 [dependabot[bot]]
|
|
67
|
+
* Update version.py [Pavel Liashkov]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## 1.1.0 (2021-04-05)
|
|
71
|
+
|
|
72
|
+
* Bump sqlalchemy from 1.4.0 to 1.4.2 [dependabot[bot]]
|
|
73
|
+
* Bump sqlalchemy from 1.4.2 to 1.4.5 [dependabot[bot]]
|
|
74
|
+
* Bump version [Pavel Liashkov]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## 1.0.0 (2021-03-17)
|
|
78
|
+
|
|
79
|
+
* Add command for checking code [Pavel Liashkov]
|
|
80
|
+
* Bump sqlalchemy from 1.3.23 to 1.4.0 [dependabot[bot]]
|
|
81
|
+
* NOTASK: Bump version [Pavel Liashkov]
|
|
82
|
+
* Bump version [Pavel Liashkov]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
## 0.1.6 (2021-02-26)
|
|
86
|
+
|
|
87
|
+
* Add codecov settings [Pavel Liashkov]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## 0.1.5 (2021-02-20)
|
|
91
|
+
|
|
92
|
+
* Update Makefile [Pavel Liashkov]
|
|
93
|
+
* Bump version [Pavel Liashkov]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## 0.1.4 (2021-02-08)
|
|
97
|
+
|
|
98
|
+
* Update readme [Pavel Liashkov]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## 0.1.3 (2021-02-02)
|
|
102
|
+
|
|
103
|
+
* Bump sqlalchemy from 1.3.22 to 1.3.23 [dependabot[bot]]
|
|
104
|
+
* Bump version [Pavel Liashkov]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## 0.1.2 (2021-01-23)
|
|
108
|
+
|
|
109
|
+
* Fix Readme [Pavel Liashkov]
|
|
110
|
+
* Bump version [Pavel Liashkov]
|
|
111
|
+
* Fix package format [Pavel Liashkov]
|
|
112
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
.PHONY: help
|
|
2
|
+
|
|
3
|
+
#################################################################################
|
|
4
|
+
# GLOBALS #
|
|
5
|
+
#################################################################################
|
|
6
|
+
|
|
7
|
+
PROJECT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
|
8
|
+
PROJECT_NAME = sqlalchemy-multiple-db
|
|
9
|
+
|
|
10
|
+
SRC_PATH = src/sqlalchemy_multiple_db
|
|
11
|
+
LINT_PATHS = src tests
|
|
12
|
+
|
|
13
|
+
UV ?= uv
|
|
14
|
+
|
|
15
|
+
#######################
|
|
16
|
+
### System commands
|
|
17
|
+
#######################
|
|
18
|
+
.PHONY: sys/changelog
|
|
19
|
+
## Generating changelog file
|
|
20
|
+
sys/changelog:
|
|
21
|
+
@echo "Generating CHANGELOG.md..."
|
|
22
|
+
@echo "" > CHANGELOG.md;
|
|
23
|
+
@previous_tag=0; \
|
|
24
|
+
for current_tag in $$(git tag --sort=-creatordate | grep '^v'); do \
|
|
25
|
+
if [ "$$previous_tag" != 0 ]; then \
|
|
26
|
+
tag_date=$$(git log -1 --pretty=format:'%ad' --date=short $${previous_tag}); \
|
|
27
|
+
printf "\n## $${previous_tag} ($${tag_date})\n\n" >> CHANGELOG.md; \
|
|
28
|
+
git log $${current_tag}...$${previous_tag} --pretty=format:'* %s [%an]' --reverse | grep -v Merge >> CHANGELOG.md; \
|
|
29
|
+
printf "\n" >> CHANGELOG.md; \
|
|
30
|
+
fi; \
|
|
31
|
+
previous_tag=$${current_tag}; \
|
|
32
|
+
done
|
|
33
|
+
@echo "CHANGELOG.md generated successfully."
|
|
34
|
+
|
|
35
|
+
.PHONY: sys/tag
|
|
36
|
+
## Create and push tag
|
|
37
|
+
sys/tag:
|
|
38
|
+
@read -p "Enter tag version (e.g., 1.0.0): " TAG; \
|
|
39
|
+
if [[ $$TAG =~ ^[0-9]+\.[0-9]+\.[0-9]+$$ ]]; then \
|
|
40
|
+
git tag -a v$$TAG -m v$$TAG; \
|
|
41
|
+
git push origin v$$TAG; \
|
|
42
|
+
echo "Tag v$$TAG created and pushed successfully."; \
|
|
43
|
+
else \
|
|
44
|
+
echo "Invalid tag format. Please use X.Y.Z (e.g., 1.0.0)"; \
|
|
45
|
+
exit 1; \
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#################################################################################
|
|
50
|
+
# VIRTUAL ENVIRONMENT #
|
|
51
|
+
#################################################################################
|
|
52
|
+
|
|
53
|
+
.PHONY: venv/install/main
|
|
54
|
+
## Install runtime dependencies
|
|
55
|
+
venv/install/main:
|
|
56
|
+
@echo "Installing runtime dependencies..."
|
|
57
|
+
$(UV) sync --no-group dev
|
|
58
|
+
@echo "done"
|
|
59
|
+
@echo
|
|
60
|
+
|
|
61
|
+
.PHONY: venv/install/all
|
|
62
|
+
## Install runtime and development dependencies
|
|
63
|
+
venv/install/all:
|
|
64
|
+
@echo "Installing runtime and development dependencies..."
|
|
65
|
+
$(UV) sync --all-groups
|
|
66
|
+
@echo "done"
|
|
67
|
+
@echo
|
|
68
|
+
|
|
69
|
+
#################################################################################
|
|
70
|
+
# COMMANDS #
|
|
71
|
+
#################################################################################
|
|
72
|
+
|
|
73
|
+
########################################
|
|
74
|
+
### Code style and static analysis
|
|
75
|
+
########################################
|
|
76
|
+
|
|
77
|
+
.PHONY: lint/ruff
|
|
78
|
+
## Check formatting and linting with Ruff
|
|
79
|
+
lint/ruff:
|
|
80
|
+
@echo "Linting with Ruff..."
|
|
81
|
+
$(UV) run ruff format --check $(LINT_PATHS)
|
|
82
|
+
$(UV) run ruff check $(LINT_PATHS)
|
|
83
|
+
@echo "done"
|
|
84
|
+
@echo
|
|
85
|
+
|
|
86
|
+
.PHONY: lint/mypy
|
|
87
|
+
## Type-check source with mypy
|
|
88
|
+
lint/mypy:
|
|
89
|
+
@echo "Type-checking with mypy..."
|
|
90
|
+
$(UV) run mypy $(SRC_PATH)
|
|
91
|
+
@echo "done"
|
|
92
|
+
@echo
|
|
93
|
+
|
|
94
|
+
.PHONY: lint
|
|
95
|
+
## Run all static checks
|
|
96
|
+
lint: lint/ruff lint/mypy
|
|
97
|
+
|
|
98
|
+
.PHONY: format
|
|
99
|
+
## Format source code and apply safe lint fixes
|
|
100
|
+
format:
|
|
101
|
+
@echo "Formatting source code..."
|
|
102
|
+
$(UV) run ruff format $(LINT_PATHS)
|
|
103
|
+
$(UV) run ruff check --fix $(LINT_PATHS)
|
|
104
|
+
@echo "done"
|
|
105
|
+
@echo
|
|
106
|
+
|
|
107
|
+
.PHONY: clean
|
|
108
|
+
## Delete generated build artifacts and caches
|
|
109
|
+
clean:
|
|
110
|
+
@echo "Clearing generated files..."
|
|
111
|
+
rm -rf .coverage .mypy_cache .pytest_cache .ruff_cache build dist
|
|
112
|
+
find . -type d -name __pycache__ -prune -exec rm -rf {} +
|
|
113
|
+
@echo "done"
|
|
114
|
+
@echo
|
|
115
|
+
|
|
116
|
+
####################
|
|
117
|
+
### Tests
|
|
118
|
+
####################
|
|
119
|
+
|
|
120
|
+
.PHONY: test
|
|
121
|
+
## Run tests with coverage
|
|
122
|
+
test:
|
|
123
|
+
$(UV) run pytest --cov=sqlalchemy_multiple_db --cov-report=term-missing
|
|
124
|
+
|
|
125
|
+
####################
|
|
126
|
+
### Distribution
|
|
127
|
+
####################
|
|
128
|
+
|
|
129
|
+
.PHONY: build
|
|
130
|
+
## Build source and wheel distributions
|
|
131
|
+
build:
|
|
132
|
+
$(UV) build
|
|
133
|
+
|
|
134
|
+
#################################################################################
|
|
135
|
+
# SELF-DOCUMENTING COMMANDS #
|
|
136
|
+
#################################################################################
|
|
137
|
+
|
|
138
|
+
.DEFAULT_GOAL := help
|
|
139
|
+
|
|
140
|
+
# Inspired by <https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html>
|
|
141
|
+
help:
|
|
142
|
+
@echo "$$(tput bold)Available rules:$$(tput sgr0)"
|
|
143
|
+
@echo
|
|
144
|
+
@sed -n -e "/^## / { \
|
|
145
|
+
h; \
|
|
146
|
+
s/.*//; \
|
|
147
|
+
:doc" \
|
|
148
|
+
-e "H; \
|
|
149
|
+
n; \
|
|
150
|
+
s/^## //; \
|
|
151
|
+
t doc" \
|
|
152
|
+
-e "s/:.*//; \
|
|
153
|
+
G; \
|
|
154
|
+
s/\\n## /---/; \
|
|
155
|
+
s/\\n/ /g; \
|
|
156
|
+
p; \
|
|
157
|
+
}" ${MAKEFILE_LIST} \
|
|
158
|
+
| LC_ALL='C' sort --ignore-case \
|
|
159
|
+
| awk -F '---' \
|
|
160
|
+
-v ncol=$$(tput cols) \
|
|
161
|
+
-v indent=19 \
|
|
162
|
+
-v col_on="$$(tput setaf 6)" \
|
|
163
|
+
-v col_off="$$(tput sgr0)" \
|
|
164
|
+
'{ \
|
|
165
|
+
printf "%s%*s%s ", col_on, -indent, $$1, col_off; \
|
|
166
|
+
n = split($$2, words, " "); \
|
|
167
|
+
line_length = ncol - indent; \
|
|
168
|
+
for (i = 1; i <= n; i++) { \
|
|
169
|
+
line_length -= length(words[i]) + 1; \
|
|
170
|
+
if (line_length <= 0) { \
|
|
171
|
+
line_length = ncol - indent - length(words[i]) - 1; \
|
|
172
|
+
printf "\n%*s ", -indent, " "; \
|
|
173
|
+
} \
|
|
174
|
+
printf "%s ", words[i]; \
|
|
175
|
+
} \
|
|
176
|
+
printf "\n"; \
|
|
177
|
+
}' \
|
|
178
|
+
| more $(shell test $(shell uname) = Darwin && echo '--no-init --raw-control-chars')
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlalchemy-multiple-db
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Explicit SQLAlchemy session management for multiple named databases
|
|
5
|
+
Project-URL: Changelog, https://github.com/bigbag/sqlalchemy-multiple-db/blob/main/CHANGELOG.md
|
|
6
|
+
Project-URL: Homepage, https://github.com/bigbag/sqlalchemy-multiple-db
|
|
7
|
+
Project-URL: Issues, https://github.com/bigbag/sqlalchemy-multiple-db/issues
|
|
8
|
+
Author-email: Pavel Liashkov <pavel.liashkov@protonmail.com>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: database,multi-database,session,sqlalchemy
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Database
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: sqlalchemy>=2.0.51
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# sqlalchemy-multiple-db
|
|
27
|
+
|
|
28
|
+
Explicit, typed SQLAlchemy 2.x session management for multiple named databases.
|
|
29
|
+
|
|
30
|
+
## Requirements
|
|
31
|
+
|
|
32
|
+
- Python 3.11, 3.12, 3.13, or 3.14
|
|
33
|
+
- SQLAlchemy 2.x (installed automatically)
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv add sqlalchemy-multiple-db
|
|
39
|
+
# or
|
|
40
|
+
uv pip install sqlalchemy-multiple-db
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from sqlalchemy import text
|
|
47
|
+
from sqlalchemy_multiple_db import DatabaseConfig, DatabaseManager
|
|
48
|
+
|
|
49
|
+
configs = {
|
|
50
|
+
"primary": DatabaseConfig(url="sqlite:///primary.db"),
|
|
51
|
+
"analytics": DatabaseConfig(url="sqlite:///analytics.db"),
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
with DatabaseManager(configs) as databases:
|
|
55
|
+
with databases.session("primary") as session:
|
|
56
|
+
session.execute(text("CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY)"))
|
|
57
|
+
session.execute(text("INSERT INTO events DEFAULT VALUES"))
|
|
58
|
+
|
|
59
|
+
with databases.session("analytics") as session:
|
|
60
|
+
session.execute(text("SELECT 1"))
|
|
61
|
+
|
|
62
|
+
assert databases.healthcheck() == {"primary": True, "analytics": True}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Each `session(name)` call creates a new SQLAlchemy `Session`. A normal block commits; an exception
|
|
66
|
+
rolls back and is re-raised; the session always closes. Call `close()` when not using the manager as a
|
|
67
|
+
context manager. `close()` is idempotent, but the manager cannot be used afterward.
|
|
68
|
+
|
|
69
|
+
## Configuration
|
|
70
|
+
|
|
71
|
+
`DatabaseConfig(url, engine_options={}, session_options={})` forwards option mappings to SQLAlchemy's
|
|
72
|
+
`create_engine` and `sessionmaker`. Options are copied at construction. The library deliberately does
|
|
73
|
+
not choose pool sizes or deprecated autocommit behavior; configure dialect-specific options explicitly
|
|
74
|
+
when needed.
|
|
75
|
+
|
|
76
|
+
`healthcheck()` runs `SELECT 1` for every configured engine and returns a `{name: bool}` mapping.
|
|
77
|
+
SQLAlchemy connection failures are logged and reported as `False` without stopping checks for other
|
|
78
|
+
databases.
|
|
79
|
+
|
|
80
|
+
## Migrating from 2.x
|
|
81
|
+
|
|
82
|
+
| 2.x | 3.0 |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| `DBConfig(dsn="...")` | `DatabaseConfig(url="...")` |
|
|
85
|
+
| `DBHelper` or global `db` | `DatabaseManager(configurations)` |
|
|
86
|
+
| `setup()` | construct the manager |
|
|
87
|
+
| `session_scope()` | `session(name)` |
|
|
88
|
+
| `get_status_info()` | `healthcheck()` |
|
|
89
|
+
| `shutdown()` | `close()` or `with DatabaseManager(...)` |
|
|
90
|
+
|
|
91
|
+
There is no global manager or implicit `default` database in 3.0. Name every database explicitly.
|
|
92
|
+
|
|
93
|
+
## Examples
|
|
94
|
+
|
|
95
|
+
Each example uses temporary SQLite files and needs no external database server:
|
|
96
|
+
|
|
97
|
+
- [basic_usage.py](examples/basic_usage.py) — create, write to, and query isolated primary and analytics databases.
|
|
98
|
+
- [transaction_rollback.py](examples/transaction_rollback.py) — verify that an exception rolls back a transaction.
|
|
99
|
+
- [healthcheck_and_options.py](examples/healthcheck_and_options.py) — configure engine/session options and inspect database health.
|
|
100
|
+
|
|
101
|
+
Run an example from a synced checkout:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
uv run python examples/basic_usage.py
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
uv sync --all-groups
|
|
111
|
+
uv run pytest
|
|
112
|
+
uv run ruff format --check src tests
|
|
113
|
+
uv run ruff check src tests
|
|
114
|
+
uv run mypy src
|
|
115
|
+
uv build
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Use `uv add <package>` to add a dependency and `uv lock --upgrade` to refresh all locked dependency
|
|
119
|
+
versions. Commit every `pyproject.toml` and `uv.lock` change together.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
Apache-2.0. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# sqlalchemy-multiple-db
|
|
2
|
+
|
|
3
|
+
Explicit, typed SQLAlchemy 2.x session management for multiple named databases.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Python 3.11, 3.12, 3.13, or 3.14
|
|
8
|
+
- SQLAlchemy 2.x (installed automatically)
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv add sqlalchemy-multiple-db
|
|
14
|
+
# or
|
|
15
|
+
uv pip install sqlalchemy-multiple-db
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from sqlalchemy import text
|
|
22
|
+
from sqlalchemy_multiple_db import DatabaseConfig, DatabaseManager
|
|
23
|
+
|
|
24
|
+
configs = {
|
|
25
|
+
"primary": DatabaseConfig(url="sqlite:///primary.db"),
|
|
26
|
+
"analytics": DatabaseConfig(url="sqlite:///analytics.db"),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
with DatabaseManager(configs) as databases:
|
|
30
|
+
with databases.session("primary") as session:
|
|
31
|
+
session.execute(text("CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY)"))
|
|
32
|
+
session.execute(text("INSERT INTO events DEFAULT VALUES"))
|
|
33
|
+
|
|
34
|
+
with databases.session("analytics") as session:
|
|
35
|
+
session.execute(text("SELECT 1"))
|
|
36
|
+
|
|
37
|
+
assert databases.healthcheck() == {"primary": True, "analytics": True}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Each `session(name)` call creates a new SQLAlchemy `Session`. A normal block commits; an exception
|
|
41
|
+
rolls back and is re-raised; the session always closes. Call `close()` when not using the manager as a
|
|
42
|
+
context manager. `close()` is idempotent, but the manager cannot be used afterward.
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
`DatabaseConfig(url, engine_options={}, session_options={})` forwards option mappings to SQLAlchemy's
|
|
47
|
+
`create_engine` and `sessionmaker`. Options are copied at construction. The library deliberately does
|
|
48
|
+
not choose pool sizes or deprecated autocommit behavior; configure dialect-specific options explicitly
|
|
49
|
+
when needed.
|
|
50
|
+
|
|
51
|
+
`healthcheck()` runs `SELECT 1` for every configured engine and returns a `{name: bool}` mapping.
|
|
52
|
+
SQLAlchemy connection failures are logged and reported as `False` without stopping checks for other
|
|
53
|
+
databases.
|
|
54
|
+
|
|
55
|
+
## Migrating from 2.x
|
|
56
|
+
|
|
57
|
+
| 2.x | 3.0 |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `DBConfig(dsn="...")` | `DatabaseConfig(url="...")` |
|
|
60
|
+
| `DBHelper` or global `db` | `DatabaseManager(configurations)` |
|
|
61
|
+
| `setup()` | construct the manager |
|
|
62
|
+
| `session_scope()` | `session(name)` |
|
|
63
|
+
| `get_status_info()` | `healthcheck()` |
|
|
64
|
+
| `shutdown()` | `close()` or `with DatabaseManager(...)` |
|
|
65
|
+
|
|
66
|
+
There is no global manager or implicit `default` database in 3.0. Name every database explicitly.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
Each example uses temporary SQLite files and needs no external database server:
|
|
71
|
+
|
|
72
|
+
- [basic_usage.py](examples/basic_usage.py) — create, write to, and query isolated primary and analytics databases.
|
|
73
|
+
- [transaction_rollback.py](examples/transaction_rollback.py) — verify that an exception rolls back a transaction.
|
|
74
|
+
- [healthcheck_and_options.py](examples/healthcheck_and_options.py) — configure engine/session options and inspect database health.
|
|
75
|
+
|
|
76
|
+
Run an example from a synced checkout:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
uv run python examples/basic_usage.py
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv sync --all-groups
|
|
86
|
+
uv run pytest
|
|
87
|
+
uv run ruff format --check src tests
|
|
88
|
+
uv run ruff check src tests
|
|
89
|
+
uv run mypy src
|
|
90
|
+
uv build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Use `uv add <package>` to add a dependency and `uv lock --upgrade` to refresh all locked dependency
|
|
94
|
+
versions. Commit every `pyproject.toml` and `uv.lock` change together.
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
Apache-2.0. See [LICENSE](LICENSE).
|