Skip to content

Commit edaa508

Browse files
committed
Use uv as the default test environment
1 parent 53e1cf5 commit edaa508

9 files changed

Lines changed: 3107 additions & 130 deletions

File tree

.github/workflows/python-ci.yaml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ jobs:
2323
with:
2424
python-version: '3.13'
2525

26+
- name: Install uv
27+
uses: astral-sh/setup-uv@v6
28+
with:
29+
enable-cache: true
30+
2631
- name: Set up Java (required for Datastore emulator)
2732
uses: actions/setup-java@v4
2833
with:
@@ -44,14 +49,7 @@ jobs:
4449
run: 'gcloud config set project python-datastore-sqlalchemy'
4550

4651
- name: Install dependencies
47-
run: |
48-
python -m pip install --upgrade pip
49-
if [ -f requirements.txt ]; then
50-
pip install -r requirements.txt
51-
else
52-
echo "No requirements.txt found"
53-
fi
52+
run: uv sync --locked
5453

5554
- name: Run tests
56-
run: |
57-
pytest
55+
run: uv run pytest

README.md

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,65 @@
1-
SQLAlchemy dialect for google cloud datastore(firestore mode)
1+
SQLAlchemy dialect for Google Cloud Datastore in Firestore mode
22
========================
3-
How to install
4-
```
5-
python3 setup.py install
6-
```
7-
or
8-
```
3+
4+
## Installation
5+
6+
Install from PyPI:
7+
```bash
98
pip install python-datastore-sqlalchemy
109
```
11-
How to use
10+
11+
Install from a local checkout:
12+
```bash
13+
uv pip install -e .
14+
```
15+
16+
Runtime dependencies are declared in `pyproject.toml`. `requirements.txt` is not used by this project.
17+
18+
## Usage
19+
1220
```python
13-
from sqlalchemy import *
14-
from sqlalchemy.engine import create_engine
15-
from sqlalchemy.schema import *
16-
engine = create_engine("datastore://my-project/?database=my-db", credentials='path/to/credentials.json')
17-
conn = engine.connect()
18-
result = conn.execute("SELECT * fro" test_table")
19-
print(result.fetchall())
21+
from sqlalchemy import create_engine, text
22+
23+
engine = create_engine(
24+
"datastore://my-project/?database=my-db",
25+
credentials="path/to/credentials.json",
26+
)
27+
28+
with engine.connect() as conn:
29+
result = conn.execute(text("SELECT * FROM test_table"))
30+
print(result.fetchall())
2031
```
2132

2233
## Preview
34+
2335
<img src="assets/pie.png">
2436

2537
> [!WARNING]
2638
> Please note: Not all GQL and SQL syntax has been fully tested. Should you encounter any bugs, please post the relevant query and open an issue on GitHub.
2739
2840
## How to contribute
41+
2942
Feel free to open issues and pull requests on GitHub.
3043

44+
## Development
45+
46+
This project uses a uv-managed virtual environment by default. The lockfile is tracked so local development and CI use the same dependency resolution.
47+
48+
Install the development environment:
49+
```bash
50+
uv sync --locked
51+
```
52+
53+
Run the test suite:
54+
```bash
55+
uv run pytest
56+
```
57+
58+
The Datastore-backed tests require the Google Cloud SDK with the `beta` and `cloud-datastore-emulator` components installed. If `gcloud` is not on `PATH`, point the test fixture at it explicitly:
59+
```bash
60+
GCLOUD_PATH=/path/to/google-cloud-sdk/bin/gcloud uv run pytest
61+
```
62+
3163
## Development Notes
32-
- [Develop a SQLAlchemy and it's dialects](https://hackmd.io/lsBW5GCVR82SORyWZ1cssA?view)
64+
65+
- [Develop a SQLAlchemy and its dialects](https://hackmd.io/lsBW5GCVR82SORyWZ1cssA?view)

pyproject.toml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,70 @@
1+
[build-system]
2+
requires = ["setuptools>=64"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "python-datastore-sqlalchemy"
7+
version = "9.0.3"
8+
description = "SQLAlchemy dialect for google cloud datastore"
9+
readme = "README.md"
10+
requires-python = ">=3.9"
11+
license = { text = "MIT" }
12+
authors = [
13+
{ name = "HY Chang(splasky)", email = "hychang.1997.tw@gmail.com" },
14+
]
15+
classifiers = [
16+
"Development Status :: 2 - Pre-Alpha",
17+
"Intended Audience :: Developers",
18+
"Programming Language :: Python",
19+
"Programming Language :: Python :: 3",
20+
"Programming Language :: Python :: Implementation :: CPython",
21+
"Topic :: Database :: Front-Ends",
22+
"Operating System :: POSIX :: Linux",
23+
]
24+
keywords = ["SQLAlchemy", "GCP", "Datastore"]
25+
dependencies = [
26+
"sqlalchemy>=1.4.16,<3.0.0",
27+
"google-cloud-datastore>=2.21.0",
28+
"google-cloud-firestore>=2.21.0",
29+
"google-cloud-bigquery>=3.35.0",
30+
"google-auth>=2.40.0",
31+
"sqlglot>=28.0.0",
32+
"pandas>=2.0.0",
33+
"requests",
34+
]
35+
36+
[project.entry-points."sqlalchemy.dialects"]
37+
datastore = "sqlalchemy_datastore:CloudDatastoreDialect"
38+
39+
[project.urls]
40+
Documentation = "https://github.com/splasky/python-datastore-sqlalchemy/wiki"
41+
Source = "https://github.com/splasky/python-datastore-sqlalchemy"
42+
Tracker = "https://github.com/splasky/python-datastore-sqlalchemy/issues"
43+
44+
[dependency-groups]
45+
dev = [
46+
"coverage==7.9.2",
47+
"flake8==7.3.0",
48+
"mypy",
49+
"pytest==9.0.3",
50+
"pytest-cov==6.2.1",
51+
"pytest-html==4.1.1",
52+
"pytest-mypy==1.0.1",
53+
"pytest-ruff==0.5",
54+
"ruff",
55+
]
56+
57+
58+
59+
[tool.setuptools.packages.find]
60+
include = ["sqlalchemy_datastore*"]
61+
62+
[tool.pytest.ini_options]
63+
addopts = "--ruff --mypy --cov --cov-report=html"
64+
pythonpath = ["."]
65+
testpaths = ["tests"]
66+
python_files = ["test_*.py"]
67+
168
[tool.ruff]
269
line-length = 120
370

pytest.ini

Lines changed: 0 additions & 24 deletions
This file was deleted.

requirements.txt

Lines changed: 0 additions & 15 deletions
This file was deleted.

setup.py

Lines changed: 8 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,70 +11,13 @@
1111
# copies or substantial portions of the Software.
1212
#
1313
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15-
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17-
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18-
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
1920

20-
import os
21-
import re
21+
from setuptools import setup
2222

23-
from setuptools import setup, find_packages
24-
25-
with open(
26-
os.path.join(os.path.dirname(__file__), "sqlalchemy_datastore", "__init__.py")
27-
) as v:
28-
version_match = re.compile(r'.*__version__ = "(.*?)"', re.S).match(v.read())
29-
if not version_match:
30-
raise RuntimeError("Unable to find version string in __init__.py.")
31-
VERSION = version_match.group(1)
32-
33-
readme = os.path.join(os.path.dirname(__file__), "README.md")
34-
with open(readme) as f:
35-
long_description = f.read()
36-
37-
38-
setup(
39-
name="python-datastore-sqlalchemy",
40-
version=VERSION,
41-
description="SQLAlchemy dialect for google cloud datastore",
42-
long_description=long_description,
43-
long_description_content_type="text/markdown",
44-
url="https://github.com/splasky/python-datastore-sqlalchemy",
45-
author="HY Chang(splasky)",
46-
author_email="hychang.1997.tw@gmail.com",
47-
license="MIT",
48-
classifiers=[
49-
"Development Status :: 2 - Pre-Alpha",
50-
"Intended Audience :: Developers",
51-
"Programming Language :: Python",
52-
"Programming Language :: Python :: 3",
53-
"Programming Language :: Python :: Implementation :: CPython",
54-
"Topic :: Database :: Front-Ends",
55-
"Operating System :: POSIX :: Linux",
56-
],
57-
keywords="SQLAlchemy GCP Datastore",
58-
python_requires=">=3.9",
59-
project_urls={
60-
"Documentation": "https://github.com/splasky/python-datastore-sqlalchemy/wiki",
61-
"Source": "https://github.com/splasky/python-datastore-sqlalchemy",
62-
"Tracker": "https://github.com/splasky/python-datastore-sqlalchemy/issues",
63-
},
64-
packages=find_packages(include=["sqlalchemy_datastore"]),
65-
include_package_data=True,
66-
install_requires=[
67-
"sqlalchemy>=1.4.16,<3.0.0",
68-
"google-cloud-datastore>=2.21.0",
69-
"google-cloud-firestore>=2.21.0",
70-
"google-cloud-bigquery>=3.35.0",
71-
"google-auth>=2.40.0",
72-
"sqlglot>=28.0.0",
73-
"pandas>=2.0.0",
74-
"requests",
75-
],
76-
zip_safe=False,
77-
entry_points={
78-
"sqlalchemy.dialects": ["datastore = sqlalchemy_datastore:CloudDatastoreDialect"]
79-
},
80-
)
23+
setup()

sqlalchemy_datastore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from .base import CloudDatastoreDialect
2121

22-
__version__ = "0.0.2"
22+
__version__ = "0.0.3"
2323

2424
__all__ = [
2525
"__version__",

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def datastore_client():
7676
"start",
7777
"--host-port=localhost:8081",
7878
"--no-store-on-disk",
79+
"--consistency=1.0",
7980
"--quiet",
8081
]
8182
)

0 commit comments

Comments
 (0)