Skip to content

Commit

Permalink
Use sqlalchemy URL function (#1158)
Browse files Browse the repository at this point in the history
- Use SQL Alchemy URL creation instead of passing a string to create_engine function
- Add Cloud SQL example to docs
  • Loading branch information
webb-ben authored Mar 30, 2023
1 parent 9debd89 commit 0f7a8a1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
19 changes: 19 additions & 0 deletions docs/source/data-publishing/ogcapi-features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,24 @@ Must have PostGIS installed.
table: hotosm_bdi_waterways
geom_field: foo_geom
The PostgreSQL provider is also able to connect to Cloud SQL databases.

.. code-block:: yaml
providers:
- type: feature
name: PostgreSQL
data:
host: /cloudsql/INSTANCE_CONNECTION_NAME # e.g. 'project:region:instance'
dbname: reference
user: postgres
password: postgres
id_field: id
table: states
This is what a configuration for `Google Cloud SQL`_ connection looks like. The ``host``
block contains the necessary socket connection information.

This provider has support for the CQL queries as indicated in the Provider table above.

.. seealso::
Expand Down Expand Up @@ -408,4 +426,5 @@ Data access examples
provider `id_field` values support slashes (i.e. ``my/cool/identifier``). The client request would then
be responsible for encoding the identifier accordingly (i.e. ``http://localhost:5000/collections/foo/items/my%2Fcool%2Fidentifier``)

.. _`Google Cloud SQL`: https://cloud.google.com/sql
.. _`OGC API - Features`: https://www.ogc.org/standards/ogcapi-features
13 changes: 8 additions & 5 deletions pygeoapi/provider/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
from pygeofilter.backends.sqlalchemy.evaluate import to_filter
import shapely
from sqlalchemy import create_engine, MetaData, PrimaryKeyConstraint, asc, desc
from sqlalchemy.engine import URL
from sqlalchemy.exc import InvalidRequestError, OperationalError
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session, load_only
Expand Down Expand Up @@ -256,11 +257,13 @@ def _get_engine_and_table_model(self):
try:
engine = _ENGINE_STORE[engine_store_key]
except KeyError:
conn_str = (
'postgresql+psycopg2://'
f'{self.db_user}:{self._db_password}@'
f'{self.db_host}:{self.db_port}/'
f'{self.db_name}'
conn_str = URL.create(
'postgresql+psycopg2',
username=self.db_user,
password=self._db_password,
host=self.db_host,
port=self.db_port,
database=self.db_name
)
engine = create_engine(
conn_str,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_postgresql_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def test_instantiation(config):
({'table': 'bad_table'}, ProviderQueryError,
'Table.*not found in schema.*'),
({'data': {'bad': 'data'}}, ProviderConnectionError,
r'Could not connect to .*None:\*\*\*@'),
r'Could not connect to postgresql\+psycopg2:\/\/:5432 \(password hidden\).'), # noqa
({'id_field': 'bad_id'}, ProviderQueryError,
r'No such id_field column \(bad_id\) on osm.hotosm_bdi_waterways.'),
])
Expand Down

0 comments on commit 0f7a8a1

Please sign in to comment.