-
Notifications
You must be signed in to change notification settings - Fork 199
feat(ibis): postgreSQL, PostGIS support for IBIS Server. #1188
Changes from 5 commits
1da65b7
5c8957e
4dc8002
d71e3e7
dea0da1
ec18377
a79b58f
3ae6bfb
5d5c1d6
c3335ff
f819515
86bb245
7e6bb0f
e20d7e8
36ea433
dfec903
2d97880
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| import base64 | ||
| from urllib.parse import quote_plus, urlparse | ||
|
|
||
| import geopandas as gpd | ||
| import orjson | ||
| import pandas as pd | ||
| import psycopg | ||
|
|
@@ -149,6 +150,19 @@ def postgres(request) -> PostgresContainer: | |
| return pg | ||
|
|
||
|
|
||
| @pytest.fixture(scope="module") | ||
| def postgis(request) -> PostgresContainer: | ||
| pg = PostgresContainer("postgis/postgis:16-3.5-alpine").start() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because I think it's better to add a comment to mention it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ohhh, yes. Completely slipped my mind.
👍 |
||
| engine = sqlalchemy.create_engine(pg.get_connection_url()) | ||
| with engine.begin() as conn: | ||
| conn.execute(text("CREATE EXTENSION IF NOT EXISTS postgis")) | ||
| gpd.read_parquet( | ||
| file_path("resource/tpch/data/cities_geometry.parquet") | ||
| ).to_postgis("cities_geometry", engine, index=False) | ||
| request.addfinalizer(pg.stop) | ||
| return pg | ||
|
|
||
|
|
||
| async def test_query(client, manifest_str, postgres: PostgresContainer): | ||
| connection_info = _to_connection_info(postgres) | ||
| response = await client.post( | ||
|
|
@@ -1050,6 +1064,25 @@ async def test_model_substitute_non_existent_column( | |
| assert 'column "x" does not exist' in response.text | ||
|
|
||
|
|
||
| async def test_postgis_geometry(client, manifest_str, postgis: PostgresContainer): | ||
| connection_info = _to_connection_info(postgis) | ||
| response = await client.post( | ||
| url=f"{base_url}/query", | ||
| json={ | ||
| "connectionInfo": connection_info, | ||
| "manifestStr": manifest_str, | ||
| "sql": ( | ||
| "SELECT ST_Distance(a.geometry, b.geometry) AS distance " | ||
| "FROM cities_geometry a, cities_geometry b " | ||
| "WHERE a.\"City\" = 'London' AND b.\"City\" = 'New York'" | ||
| ), | ||
| }, | ||
| ) | ||
| assert response.status_code == 200 | ||
| result = response.json() | ||
| assert result["data"][0] == ["74.6626535"] | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| def _to_connection_info(pg: PostgresContainer): | ||
| return { | ||
| "host": pg.get_container_host_ip(), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify extension handler augmentation behavior
The
augmentmethod signature returns a list of tables, but it's being used here to modify theunique_tablesdictionary. Since Python dictionaries are passed by reference, this likely works as intended, but it would be clearer if the method returned the modified dictionary or the variable assignment was removed.🏁 Script executed:
Length of output: 1566
🏁 Script executed:
Length of output: 3870
🏁 Script executed:
Length of output: 19056
Fix type annotations for ExtensionHandler.augment and handlers
The
augmentand related handler methods actually accept and return a mapping of table names toTableobjects (adict[str, Table]), not alist[Table]. Update the type signatures to reflect that, or else change the implementation to work with lists:• In ibis-server/app/model/metadata/postgres.py, adjust:
• Optionally remove the assignment
Since the handlers mutate the dict in place and then return it, you could also call:
without re-assigning
unique_tables.These changes will make the code’s behavior and its annotations consistent.