sqlalchemy-postgres-point 0.1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sqlalchemy-postgres-point
3
- Version: 0.1.1
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
  ![GitHub CI Status](https://github.com/iloveitaly/sqlalchemy-postgres-point/actions/workflows/build_and_publish.yml/badge.svg)
16
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
- Or with pip:
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,54 +106,55 @@ DROP EXTENSION IF EXISTS cube;
119
106
  """)
120
107
  ```
121
108
 
122
- **Integration Steps:**
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
- -------
119
+ ## Alembic Integration
135
120
 
136
- Run the test suite with:
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`:
137
122
 
138
- ```bash
139
- uv run pytest -q
123
+ ```python
124
+ from sqlalchemy_postgres_point.alembic_integration import render_item
125
+
126
+ # in run_migrations_online and run_migrations_offline:
127
+ context.configure(
128
+ # ... other options ...
129
+ render_item=render_item,
130
+ )
140
131
  ```
141
132
 
142
- Development
143
- -----------
133
+ Once wired up, `from sqlalchemy_postgres_point import PointType` will be automatically included in generated migration files whenever a `PointType` column is detected.
144
134
 
145
- After cloning:
135
+ ### Chaining `render_item`
146
136
 
147
- ```bash
148
- uv sync # installs runtime + dev deps
149
- uv run pytest -q
150
- ```
137
+ It's insane to me, but you have to chain multiple `render_item` instances you may have yourself.
151
138
 
152
- Project Structure
153
- -----------------
139
+ ```python
140
+ from sqlalchemy_postgres_point.alembic_integration import render_item as render_point
141
+
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
+ ```
154
149
 
155
- * `sqlalchemy_postgres_point/point.py` – Implementation of `PointType`.
156
- * `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.
157
151
 
158
- Limitations / Notes
159
- -------------------
152
+ ## Limitations / Notes
160
153
 
161
- * No automatic validation of longitude/latitude ranges; add your own if required.
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`.
162
155
  * Uses simple textual representation `(lng,lat)` accepted by PostgreSQL `POINT` input parser.
163
156
  * If you need advanced spatial indexing / SRID support, look at GeoAlchemy2/PostGIS instead.
164
157
 
165
- License
166
- -------
167
-
168
- MIT (see your project's LICENSE file if added later). Contributions welcome.
169
-
170
158
  ---
171
159
 
172
160
  *This project was created from [iloveitaly/python-package-template](https://github.com/iloveitaly/python-package-template)*
@@ -3,18 +3,15 @@
3
3
  ![GitHub CI Status](https://github.com/iloveitaly/sqlalchemy-postgres-point/actions/workflows/build_and_publish.yml/badge.svg)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
- Or with pip:
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,54 +94,55 @@ DROP EXTENSION IF EXISTS cube;
107
94
  """)
108
95
  ```
109
96
 
110
- **Integration Steps:**
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
- -------
107
+ ## Alembic Integration
123
108
 
124
- Run the test suite with:
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`:
125
110
 
126
- ```bash
127
- uv run pytest -q
111
+ ```python
112
+ from sqlalchemy_postgres_point.alembic_integration import render_item
113
+
114
+ # in run_migrations_online and run_migrations_offline:
115
+ context.configure(
116
+ # ... other options ...
117
+ render_item=render_item,
118
+ )
128
119
  ```
129
120
 
130
- Development
131
- -----------
121
+ Once wired up, `from sqlalchemy_postgres_point import PointType` will be automatically included in generated migration files whenever a `PointType` column is detected.
132
122
 
133
- After cloning:
123
+ ### Chaining `render_item`
134
124
 
135
- ```bash
136
- uv sync # installs runtime + dev deps
137
- uv run pytest -q
138
- ```
125
+ It's insane to me, but you have to chain multiple `render_item` instances you may have yourself.
139
126
 
140
- Project Structure
141
- -----------------
127
+ ```python
128
+ from sqlalchemy_postgres_point.alembic_integration import render_item as render_point
129
+
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
+ ```
142
137
 
143
- * `sqlalchemy_postgres_point/point.py` – Implementation of `PointType`.
144
- * `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.
145
139
 
146
- Limitations / Notes
147
- -------------------
140
+ ## Limitations / Notes
148
141
 
149
- * No automatic validation of longitude/latitude ranges; add your own if required.
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`.
150
143
  * Uses simple textual representation `(lng,lat)` accepted by PostgreSQL `POINT` input parser.
151
144
  * If you need advanced spatial indexing / SRID support, look at GeoAlchemy2/PostGIS instead.
152
145
 
153
- License
154
- -------
155
-
156
- MIT (see your project's LICENSE file if added later). Contributions welcome.
157
-
158
146
  ---
159
147
 
160
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.1.1"
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.10.0"]
24
+ requires = ["uv_build>=0.11.0,<0.12"]
25
25
  build-backend = "uv_build"
26
26
 
27
27
  [tool.uv.build-backend]
@@ -39,6 +39,7 @@ dev = [
39
39
  "coverage>=7.13.4",
40
40
  "pytest-cov>=7.0.0",
41
41
  "covdefaults>=2.3.0",
42
+ "alembic>=1.16.5",
42
43
  ]
43
44
 
44
45
  [tool.pyright]
@@ -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