sqlalchemy-postgres-point 0.2.0__tar.gz → 0.2.1__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_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/PKG-INFO +26 -65
- {sqlalchemy_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/README.md +25 -64
- {sqlalchemy_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/pyproject.toml +2 -2
- sqlalchemy_postgres_point-0.2.1/sqlalchemy_postgres_point/alembic_integration.py +32 -0
- sqlalchemy_postgres_point-0.2.0/sqlalchemy_postgres_point/alembic_integration.py +0 -56
- {sqlalchemy_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/sqlalchemy_postgres_point/__init__.py +0 -0
- {sqlalchemy_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/sqlalchemy_postgres_point/point.py +0 -0
- {sqlalchemy_postgres_point-0.2.0 → sqlalchemy_postgres_point-0.2.1}/sqlalchemy_postgres_point/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: sqlalchemy-postgres-point
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Lightweight SQLAlchemy custom type for PostgreSQL POINT columns with tuple binding and an earth-distance comparator.
|
|
5
5
|
Keywords: sqlalchemy,postgresql,point,geometry,geospatial,gis,database,types,earthdistance
|
|
6
6
|
Author: Michael Bianco
|
|
@@ -15,18 +15,15 @@ Description-Content-Type: text/markdown
|
|
|
15
15
|

|
|
16
16
|
[](https://opensource.org/licenses/MIT)
|
|
17
17
|
|
|
18
|
-
sqlalchemy-postgres-point
|
|
19
|
-
=========================
|
|
18
|
+
# sqlalchemy-postgres-point
|
|
20
19
|
|
|
21
20
|
Lightweight, pure-Python SQLAlchemy custom type for PostgreSQL `POINT` columns.
|
|
22
21
|
|
|
23
|
-
Why
|
|
24
|
-
----
|
|
22
|
+
## Why
|
|
25
23
|
|
|
26
24
|
PostgreSQL has a native `POINT` type (stored internally as a pair of float8 values). SQLAlchemy does not ship a dedicated high-level type wrapper for simple geometric primitives. This package provides a very small `PointType` you can use immediately without pulling in a full spatial stack (e.g. PostGIS + GeoAlchemy2) when all you need is storing and retrieving `(longitude, latitude)` pairs.
|
|
27
25
|
|
|
28
|
-
Features
|
|
29
|
-
--------
|
|
26
|
+
## Features
|
|
30
27
|
|
|
31
28
|
* Simple `(lng, lat)` tuple binding and result conversion.
|
|
32
29
|
* Safe NULL handling.
|
|
@@ -34,23 +31,13 @@ Features
|
|
|
34
31
|
* Custom comparator exposing the PostgreSQL earth-distance `<@>` operator (returns a `Float`).
|
|
35
32
|
* `cache_ok = True` for SQLAlchemy 2.x compilation caching.
|
|
36
33
|
|
|
37
|
-
Installation
|
|
38
|
-
------------
|
|
39
|
-
|
|
40
|
-
Using `uv` (recommended):
|
|
34
|
+
## Installation
|
|
41
35
|
|
|
42
36
|
```bash
|
|
43
37
|
uv add sqlalchemy-postgres-point
|
|
44
38
|
```
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pip install sqlalchemy-postgres-point
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Usage
|
|
53
|
-
-----
|
|
40
|
+
## Usage
|
|
54
41
|
|
|
55
42
|
```python
|
|
56
43
|
from sqlalchemy import Column, Integer
|
|
@@ -119,81 +106,55 @@ DROP EXTENSION IF EXISTS cube;
|
|
|
119
106
|
""")
|
|
120
107
|
```
|
|
121
108
|
|
|
122
|
-
|
|
109
|
+
#### Integration Steps
|
|
123
110
|
|
|
124
111
|
1. Generate a new migration: `alembic revision -m "add_postgres_extensions"`
|
|
125
112
|
2. Copy the `upgrade()` and `downgrade()` functions above into your new migration file
|
|
126
113
|
3. Run the migration: `alembic upgrade head`
|
|
127
114
|
|
|
128
|
-
Returned Python Values
|
|
129
|
-
----------------------
|
|
115
|
+
## Returned Python Values
|
|
130
116
|
|
|
131
117
|
Values are loaded as a 2-tuple of floats `(lng, lat)` or `None` when NULL.
|
|
132
118
|
|
|
133
|
-
Testing
|
|
134
|
-
-------
|
|
135
|
-
|
|
136
|
-
Run the test suite with:
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
uv run pytest -q
|
|
140
|
-
```
|
|
141
|
-
|
|
142
119
|
## Alembic Integration
|
|
143
120
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
First, import the integration module:
|
|
121
|
+
To ensure generated migration files include the correct `PointType` import, pass the provided `render_item` hook to `context.configure()` in your `alembic/env.py`:
|
|
147
122
|
|
|
148
123
|
```python
|
|
149
|
-
|
|
150
|
-
```
|
|
124
|
+
from sqlalchemy_postgres_point.alembic_integration import render_item
|
|
151
125
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
```python
|
|
155
|
-
def render_item(type_, obj, autogen_context):
|
|
156
|
-
if type_ == "type" and type(obj).__name__ == "PointType":
|
|
157
|
-
return sqlalchemy_postgres_point.alembic_integration.render_point_type(obj, obj, autogen_context)
|
|
158
|
-
return False
|
|
159
|
-
|
|
160
|
-
# ... in run_migrations_online and run_migrations_offline ...
|
|
126
|
+
# in run_migrations_online and run_migrations_offline:
|
|
161
127
|
context.configure(
|
|
162
128
|
# ... other options ...
|
|
163
129
|
render_item=render_item,
|
|
164
130
|
)
|
|
165
131
|
```
|
|
166
132
|
|
|
167
|
-
Once
|
|
133
|
+
Once wired up, `from sqlalchemy_postgres_point import PointType` will be automatically included in generated migration files whenever a `PointType` column is detected.
|
|
168
134
|
|
|
169
|
-
|
|
170
|
-
-----------
|
|
135
|
+
### Chaining `render_item`
|
|
171
136
|
|
|
172
|
-
|
|
137
|
+
It's insane to me, but you have to chain multiple `render_item` instances you may have yourself.
|
|
173
138
|
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
uv run pytest -q
|
|
177
|
-
```
|
|
139
|
+
```python
|
|
140
|
+
from sqlalchemy_postgres_point.alembic_integration import render_item as render_point
|
|
178
141
|
|
|
179
|
-
|
|
180
|
-
|
|
142
|
+
def render_item(type_, obj, autogen_context):
|
|
143
|
+
return (
|
|
144
|
+
render_point(type_, obj, autogen_context)
|
|
145
|
+
or other_package.render_item(type_, obj, autogen_context)
|
|
146
|
+
or False
|
|
147
|
+
)
|
|
148
|
+
```
|
|
181
149
|
|
|
182
|
-
|
|
183
|
-
* `tests/test_point.py` – Unit tests for processors and comparator.
|
|
150
|
+
Or you could use something like [`some_fn`](https://funcy.readthedocs.io/en/stable/funcs.html#some_fn) to make this even cleaner.
|
|
184
151
|
|
|
185
|
-
Limitations / Notes
|
|
186
|
-
-------------------
|
|
152
|
+
## Limitations / Notes
|
|
187
153
|
|
|
188
|
-
*
|
|
154
|
+
* Coordinates are validated on both write and read: longitude must be within `[-180, 180]`, latitude within `[-90, 90]`, and non-finite values (`NaN`, `inf`) are rejected with a `ValueError`.
|
|
189
155
|
* Uses simple textual representation `(lng,lat)` accepted by PostgreSQL `POINT` input parser.
|
|
190
156
|
* If you need advanced spatial indexing / SRID support, look at GeoAlchemy2/PostGIS instead.
|
|
191
157
|
|
|
192
|
-
License
|
|
193
|
-
-------
|
|
194
|
-
|
|
195
|
-
MIT (see your project's LICENSE file if added later). Contributions welcome.
|
|
196
|
-
|
|
197
158
|
---
|
|
198
159
|
|
|
199
160
|
*This project was created from [iloveitaly/python-package-template](https://github.com/iloveitaly/python-package-template)*
|
|
@@ -3,18 +3,15 @@
|
|
|
3
3
|

|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
sqlalchemy-postgres-point
|
|
7
|
-
=========================
|
|
6
|
+
# sqlalchemy-postgres-point
|
|
8
7
|
|
|
9
8
|
Lightweight, pure-Python SQLAlchemy custom type for PostgreSQL `POINT` columns.
|
|
10
9
|
|
|
11
|
-
Why
|
|
12
|
-
----
|
|
10
|
+
## Why
|
|
13
11
|
|
|
14
12
|
PostgreSQL has a native `POINT` type (stored internally as a pair of float8 values). SQLAlchemy does not ship a dedicated high-level type wrapper for simple geometric primitives. This package provides a very small `PointType` you can use immediately without pulling in a full spatial stack (e.g. PostGIS + GeoAlchemy2) when all you need is storing and retrieving `(longitude, latitude)` pairs.
|
|
15
13
|
|
|
16
|
-
Features
|
|
17
|
-
--------
|
|
14
|
+
## Features
|
|
18
15
|
|
|
19
16
|
* Simple `(lng, lat)` tuple binding and result conversion.
|
|
20
17
|
* Safe NULL handling.
|
|
@@ -22,23 +19,13 @@ Features
|
|
|
22
19
|
* Custom comparator exposing the PostgreSQL earth-distance `<@>` operator (returns a `Float`).
|
|
23
20
|
* `cache_ok = True` for SQLAlchemy 2.x compilation caching.
|
|
24
21
|
|
|
25
|
-
Installation
|
|
26
|
-
------------
|
|
27
|
-
|
|
28
|
-
Using `uv` (recommended):
|
|
22
|
+
## Installation
|
|
29
23
|
|
|
30
24
|
```bash
|
|
31
25
|
uv add sqlalchemy-postgres-point
|
|
32
26
|
```
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
pip install sqlalchemy-postgres-point
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Usage
|
|
41
|
-
-----
|
|
28
|
+
## Usage
|
|
42
29
|
|
|
43
30
|
```python
|
|
44
31
|
from sqlalchemy import Column, Integer
|
|
@@ -107,81 +94,55 @@ DROP EXTENSION IF EXISTS cube;
|
|
|
107
94
|
""")
|
|
108
95
|
```
|
|
109
96
|
|
|
110
|
-
|
|
97
|
+
#### Integration Steps
|
|
111
98
|
|
|
112
99
|
1. Generate a new migration: `alembic revision -m "add_postgres_extensions"`
|
|
113
100
|
2. Copy the `upgrade()` and `downgrade()` functions above into your new migration file
|
|
114
101
|
3. Run the migration: `alembic upgrade head`
|
|
115
102
|
|
|
116
|
-
Returned Python Values
|
|
117
|
-
----------------------
|
|
103
|
+
## Returned Python Values
|
|
118
104
|
|
|
119
105
|
Values are loaded as a 2-tuple of floats `(lng, lat)` or `None` when NULL.
|
|
120
106
|
|
|
121
|
-
Testing
|
|
122
|
-
-------
|
|
123
|
-
|
|
124
|
-
Run the test suite with:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
uv run pytest -q
|
|
128
|
-
```
|
|
129
|
-
|
|
130
107
|
## Alembic Integration
|
|
131
108
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
First, import the integration module:
|
|
109
|
+
To ensure generated migration files include the correct `PointType` import, pass the provided `render_item` hook to `context.configure()` in your `alembic/env.py`:
|
|
135
110
|
|
|
136
111
|
```python
|
|
137
|
-
|
|
138
|
-
```
|
|
112
|
+
from sqlalchemy_postgres_point.alembic_integration import render_item
|
|
139
113
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```python
|
|
143
|
-
def render_item(type_, obj, autogen_context):
|
|
144
|
-
if type_ == "type" and type(obj).__name__ == "PointType":
|
|
145
|
-
return sqlalchemy_postgres_point.alembic_integration.render_point_type(obj, obj, autogen_context)
|
|
146
|
-
return False
|
|
147
|
-
|
|
148
|
-
# ... in run_migrations_online and run_migrations_offline ...
|
|
114
|
+
# in run_migrations_online and run_migrations_offline:
|
|
149
115
|
context.configure(
|
|
150
116
|
# ... other options ...
|
|
151
117
|
render_item=render_item,
|
|
152
118
|
)
|
|
153
119
|
```
|
|
154
120
|
|
|
155
|
-
Once
|
|
121
|
+
Once wired up, `from sqlalchemy_postgres_point import PointType` will be automatically included in generated migration files whenever a `PointType` column is detected.
|
|
156
122
|
|
|
157
|
-
|
|
158
|
-
-----------
|
|
123
|
+
### Chaining `render_item`
|
|
159
124
|
|
|
160
|
-
|
|
125
|
+
It's insane to me, but you have to chain multiple `render_item` instances you may have yourself.
|
|
161
126
|
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
uv run pytest -q
|
|
165
|
-
```
|
|
127
|
+
```python
|
|
128
|
+
from sqlalchemy_postgres_point.alembic_integration import render_item as render_point
|
|
166
129
|
|
|
167
|
-
|
|
168
|
-
|
|
130
|
+
def render_item(type_, obj, autogen_context):
|
|
131
|
+
return (
|
|
132
|
+
render_point(type_, obj, autogen_context)
|
|
133
|
+
or other_package.render_item(type_, obj, autogen_context)
|
|
134
|
+
or False
|
|
135
|
+
)
|
|
136
|
+
```
|
|
169
137
|
|
|
170
|
-
|
|
171
|
-
* `tests/test_point.py` – Unit tests for processors and comparator.
|
|
138
|
+
Or you could use something like [`some_fn`](https://funcy.readthedocs.io/en/stable/funcs.html#some_fn) to make this even cleaner.
|
|
172
139
|
|
|
173
|
-
Limitations / Notes
|
|
174
|
-
-------------------
|
|
140
|
+
## Limitations / Notes
|
|
175
141
|
|
|
176
|
-
*
|
|
142
|
+
* Coordinates are validated on both write and read: longitude must be within `[-180, 180]`, latitude within `[-90, 90]`, and non-finite values (`NaN`, `inf`) are rejected with a `ValueError`.
|
|
177
143
|
* Uses simple textual representation `(lng,lat)` accepted by PostgreSQL `POINT` input parser.
|
|
178
144
|
* If you need advanced spatial indexing / SRID support, look at GeoAlchemy2/PostGIS instead.
|
|
179
145
|
|
|
180
|
-
License
|
|
181
|
-
-------
|
|
182
|
-
|
|
183
|
-
MIT (see your project's LICENSE file if added later). Contributions welcome.
|
|
184
|
-
|
|
185
146
|
---
|
|
186
147
|
|
|
187
148
|
*This project was created from [iloveitaly/python-package-template](https://github.com/iloveitaly/python-package-template)*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sqlalchemy-postgres-point"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
description = "Lightweight SQLAlchemy custom type for PostgreSQL POINT columns with tuple binding and an earth-distance comparator."
|
|
5
5
|
keywords = [
|
|
6
6
|
"sqlalchemy",
|
|
@@ -21,7 +21,7 @@ urls = { "Repository" = "https://github.com/iloveitaly/sqlalchemy-postgres-point
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
[build-system]
|
|
24
|
-
requires = ["uv_build>=0.
|
|
24
|
+
requires = ["uv_build>=0.11.0,<0.12"]
|
|
25
25
|
build-backend = "uv_build"
|
|
26
26
|
|
|
27
27
|
[tool.uv.build-backend]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Alembic integration for rendering PointType in generated migration files.
|
|
3
|
+
|
|
4
|
+
Usage — add two lines to your alembic/env.py:
|
|
5
|
+
|
|
6
|
+
from sqlalchemy_postgres_point.alembic_integration import render_item
|
|
7
|
+
|
|
8
|
+
Then pass it to both context.configure() calls:
|
|
9
|
+
|
|
10
|
+
context.configure(
|
|
11
|
+
...,
|
|
12
|
+
render_item=render_item,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
Once wired up, ``from sqlalchemy_postgres_point import PointType`` will be
|
|
16
|
+
automatically included in generated migration files whenever PointType is used.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .point import PointType
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def render_item(type_, obj, autogen_context):
|
|
23
|
+
"""Alembic render_item hook that handles PointType columns.
|
|
24
|
+
|
|
25
|
+
Returns "PointType()" and registers the import when the rendered item is a
|
|
26
|
+
PointType instance. Returns False for everything else so Alembic falls back
|
|
27
|
+
to its default rendering.
|
|
28
|
+
"""
|
|
29
|
+
if type_ == "type" and isinstance(obj, PointType):
|
|
30
|
+
autogen_context.imports.add("from sqlalchemy_postgres_point import PointType")
|
|
31
|
+
return "PointType()"
|
|
32
|
+
return False
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Alembic integration to automatically add imports for PointType in migration files.
|
|
3
|
-
|
|
4
|
-
This module hooks into Alembic's autogenerate system to automatically include
|
|
5
|
-
the necessary import statement when PointType is detected in models.
|
|
6
|
-
|
|
7
|
-
Usage:
|
|
8
|
-
Add this import to your alembic/env.py file:
|
|
9
|
-
|
|
10
|
-
import sqlalchemy_postgres_point.alembic_integration
|
|
11
|
-
|
|
12
|
-
Once added, `from sqlalchemy_postgres_point import PointType` will be automatically
|
|
13
|
-
included in generated migration files.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
import alembic.autogenerate
|
|
17
|
-
import alembic.operations.ops
|
|
18
|
-
from sqlalchemy.types import UserDefinedType
|
|
19
|
-
|
|
20
|
-
from .point import PointType
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def render_point_type(type_, object_, autogen_context):
|
|
24
|
-
"""Render PointType in migration files with proper import."""
|
|
25
|
-
# Add the import to the migration file
|
|
26
|
-
autogen_context.imports.add("from sqlalchemy_postgres_point import PointType")
|
|
27
|
-
return "PointType()"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# Register the renderer for PointType
|
|
31
|
-
alembic.autogenerate.render.renderers.dispatch_for(PointType, replace=True)(
|
|
32
|
-
render_point_type
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# Also register for UserDefinedType as a fallback if the class doesn't match exactly
|
|
37
|
-
@alembic.autogenerate.render.renderers.dispatch_for(UserDefinedType, replace=True)
|
|
38
|
-
def render_user_defined_type(type_, object_, autogen_context):
|
|
39
|
-
if type(object_).__name__ == "PointType":
|
|
40
|
-
return render_point_type(type_, object_, autogen_context)
|
|
41
|
-
return False
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@alembic.autogenerate.comparators.dispatch_for("schema")
|
|
45
|
-
def compare_point_types(
|
|
46
|
-
autogen_context: alembic.autogenerate.api.AutogenContext,
|
|
47
|
-
upgrade_ops: alembic.operations.ops.UpgradeOps,
|
|
48
|
-
schema_names,
|
|
49
|
-
):
|
|
50
|
-
"""
|
|
51
|
-
Hook into Alembic's schema comparison to detect PointType usage.
|
|
52
|
-
|
|
53
|
-
This ensures the import is added even if PointType is used in existing
|
|
54
|
-
columns that might not trigger the render hook directly.
|
|
55
|
-
"""
|
|
56
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|