GeoAlchemy2 0.15.2__tar.gz → 0.17.0__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.
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/workflows/test_and_publish.yml +63 -26
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.pre-commit-config.yaml +3 -5
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/CHANGES.txt +14 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0/GeoAlchemy2.egg-info}/PKG-INFO +14 -2
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2.egg-info/SOURCES.txt +13 -1
- geoalchemy2-0.17.0/GeoAlchemy2.egg-info/entry_points.txt +2 -0
- {geoalchemy2-0.15.2/GeoAlchemy2.egg-info → geoalchemy2-0.17.0}/PKG-INFO +14 -2
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/admin.rst +8 -3
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/core_tutorial.rst +14 -2
- geoalchemy2-0.17.0/doc/dialect_specific_features.rst +13 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/index.rst +8 -3
- geoalchemy2-0.17.0/doc/mysql_mariadb_dialect.rst +43 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/orm_tutorial.rst +15 -1
- geoalchemy2-0.17.0/doc/plugin.rst +9 -0
- geoalchemy2-0.15.2/doc/spatialite_tutorial.rst → geoalchemy2-0.17.0/doc/spatialite_dialect.rst +14 -106
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/__init__.py +2 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/__init__.py +4 -4
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/__init__.py +1 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/common.py +5 -5
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/geopackage.py +7 -3
- geoalchemy2-0.17.0/geoalchemy2/admin/dialects/mariadb.py +134 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/mysql.py +27 -11
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/sqlite.py +10 -5
- geoalchemy2-0.17.0/geoalchemy2/admin/plugin.py +98 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/shape.py +0 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/__init__.py +7 -7
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/__init__.py +1 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/common.py +1 -1
- geoalchemy2-0.17.0/geoalchemy2/types/dialects/mariadb.py +47 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/pyproject.toml +3 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/requirements.txt +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/setup.py +5 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/Dockerfile +2 -2
- geoalchemy2-0.17.0/test_container/Dockerfile_mariadb +19 -0
- geoalchemy2-0.17.0/test_container/build_mariadb.sh +7 -0
- geoalchemy2-0.17.0/test_container/helpers/init_mariadb.sh +22 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/helpers/init_mysql.sh +2 -1
- geoalchemy2-0.17.0/test_container/run_mariadb.sh +12 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/__init__.py +4 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/conftest.py +85 -25
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_orm_mapped_v2.py +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_summarystatsagg.py +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/schema_fixtures.py +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_alembic_migrations.py +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functional.py +85 -19
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functional_mysql.py +19 -8
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functional_postgresql.py +1 -1
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_pickle.py +1 -1
- geoalchemy2-0.17.0/tests/test_plugin.py +90 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_shape.py +21 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tox.ini +12 -7
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.codespellrc +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.coveragerc +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.flake8 +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/ISSUE_TEMPLATE/how_to_use.yaml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/dependabot.yml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.github/pull_request_template.md +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.gitignore +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/.readthedocs.yaml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/COPYING.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2.egg-info/dependency_links.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2.egg-info/not-zip-safe +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2.egg-info/requires.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2.egg-info/top_level.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/GeoAlchemy2_dev.yml +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/MANIFEST.in +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/README.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/RELEASE.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/TEST.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/Makefile +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_static/geoalchemy.png +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_static/geoalchemy.svg +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_static/geoalchemy_small.png +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_static/geoalchemy_small.svg +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_templates/sidebar-about.html +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_templates/sidebar-links.html +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_templates/sidebar-logo.html +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/LICENSE +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/README +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/flask/layout.html +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/flask/relations.html +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/flask/static/flasky.css_t +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/flask/static/small_flask.css +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/_themes/flask/theme.conf +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/alembic.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/alembic_helpers.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/changelog.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/conf.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/elements.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/make.bat +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/migrate.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/shape.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/spatial_functions.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/spatial_operators.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/doc/types.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/generate_type_stubs.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/_functions.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/_functions_helpers.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/admin/dialects/postgresql.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/alembic_helpers.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/comparator.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/elements.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/exc.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/functions.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/functions.pyi +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/py.typed +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/geopackage.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/mysql.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/postgresql.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/types/dialects/sqlite.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/geoalchemy2/utils.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/requirements-doc.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/requirements-mypy.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/requirements-rtd.txt +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/setup.cfg +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/.dockerignore +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/.gitignore +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/build.sh +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/helpers/entrypoint.sh +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/helpers/init_postgres.sh +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/helpers/install_requirements.sh +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/test_container/run.sh +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/alembic_config/alembic.ini +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/data/spatialite_ge_4.sqlite +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/data/spatialite_geopackage.gpkg +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/data/spatialite_lt_4.sqlite +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/README.rst +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/__init__.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_decipher_raster.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_disable_wrapping.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_insert_raster.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_length_at_insert.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_raster_transform.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_specific_compilation.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/gallery/test_type_decorator.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_comparator.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_elements.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functional_geopackage.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functional_sqlite.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_functions.py +0 -0
- {geoalchemy2-0.15.2 → geoalchemy2-0.17.0}/tests/test_types.py +0 -0
@@ -33,7 +33,7 @@ jobs:
|
|
33
33
|
{"pkg_name": "python==3.10.*", "flag": "3.10"},
|
34
34
|
{"pkg_name": "python==3.11.*", "flag": "3.11"},
|
35
35
|
{"pkg_name": "python==3.12.*", "flag": "3.12"},
|
36
|
-
{"pkg_name": "pypy3.
|
36
|
+
{"pkg_name": "pypy3.10", "flag": "pypy3.10"},
|
37
37
|
]
|
38
38
|
|
39
39
|
# The type of runner that the job will run on
|
@@ -54,28 +54,54 @@ jobs:
|
|
54
54
|
--health-interval 10s
|
55
55
|
--health-timeout 5s
|
56
56
|
--health-retries 5
|
57
|
+
mysql:
|
58
|
+
image: mysql:latest
|
59
|
+
ports:
|
60
|
+
- 3307:3306
|
61
|
+
env:
|
62
|
+
MYSQL_USER: gis
|
63
|
+
MYSQL_PASSWORD: gis
|
64
|
+
MYSQL_DATABASE: gis
|
65
|
+
MYSQL_ROOT_PASSWORD: gis
|
66
|
+
# Set health checks to wait until MySQL has started
|
67
|
+
options: >-
|
68
|
+
--health-cmd="mysqladmin ping"
|
69
|
+
--health-interval=10s
|
70
|
+
--health-timeout=5s
|
71
|
+
--health-retries=3
|
72
|
+
mariadb:
|
73
|
+
image: mariadb:latest
|
74
|
+
ports:
|
75
|
+
- 3308:3306
|
76
|
+
env:
|
77
|
+
MARIADB_USER: gis
|
78
|
+
MARIADB_PASSWORD: gis
|
79
|
+
MARIADB_DATABASE: gis
|
80
|
+
MARIADB_ROOT_PASSWORD: gis
|
81
|
+
# Set health checks to wait until MariaDB has started
|
82
|
+
options: >-
|
83
|
+
--health-cmd="healthcheck.sh --connect --innodb_initialized"
|
84
|
+
--health-interval=10s
|
85
|
+
--health-timeout=5s
|
86
|
+
--health-retries=3
|
87
|
+
|
57
88
|
|
58
89
|
steps:
|
59
90
|
|
60
91
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
61
92
|
- uses: actions/checkout@v4
|
62
93
|
|
63
|
-
# Setup
|
64
|
-
- name:
|
65
|
-
uses:
|
94
|
+
# Setup Python
|
95
|
+
- name: Set up Python ${{ matrix.python-version }}
|
96
|
+
uses: actions/setup-python@v5
|
66
97
|
with:
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
condarc: |
|
75
|
-
channels:
|
76
|
-
- conda-forge
|
77
|
-
- defaults
|
78
|
-
channel_priority: strict
|
98
|
+
python-version: ${{ matrix.python-version.flag }}
|
99
|
+
|
100
|
+
# Install MariaDB
|
101
|
+
- name: Install MariaDB and SpatiaLite
|
102
|
+
run: |
|
103
|
+
sudo apt-get update
|
104
|
+
sudo apt-get install -y mariadb-server mariadb-client libsqlite3-mod-spatialite libgdal-dev gdal-bin rasterio
|
79
105
|
|
80
106
|
# Config PostgreSQL
|
81
107
|
- name: Configure PostgreSQL
|
@@ -95,13 +121,17 @@ jobs:
|
|
95
121
|
# Drop PostGIS Topology extension to "gis" database
|
96
122
|
psql -h localhost -p 5432 -U gis -d gis -c 'DROP EXTENSION IF EXISTS postgis_topology;'
|
97
123
|
|
98
|
-
#
|
99
|
-
- name:
|
124
|
+
# Check MySQL
|
125
|
+
- name: Check MySQL
|
126
|
+
run: |
|
127
|
+
mysql --user=gis --password=gis --host=127.0.0.1 -P 3307 -e "SELECT VERSION();"
|
128
|
+
mysql --user=root --password=gis --host=127.0.0.1 -P 3307 -e "GRANT ALL PRIVILEGES ON *.* TO 'gis'@'%' WITH GRANT OPTION;"
|
129
|
+
|
130
|
+
# Check MariaDB
|
131
|
+
- name: Check MariaDB
|
100
132
|
run: |
|
101
|
-
|
102
|
-
|
103
|
-
sudo mysql --user=root --password=root --host=127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO 'gis'@'%' WITH GRANT OPTION;"
|
104
|
-
mysql --user=gis --password=gis -e "CREATE DATABASE gis;"
|
133
|
+
mysql --user=gis --password=gis --host=127.0.0.1 -P 3308 -e "SELECT VERSION();"
|
134
|
+
mysql --user=root --password=gis --host=127.0.0.1 -P 3308 -e "GRANT ALL PRIVILEGES ON *.* TO 'gis'@'%' WITH GRANT OPTION;"
|
105
135
|
|
106
136
|
# Check python version
|
107
137
|
- name: Display Python version
|
@@ -114,16 +144,23 @@ jobs:
|
|
114
144
|
- name: Install dependencies
|
115
145
|
run: |
|
116
146
|
python -m pip install --upgrade pip setuptools
|
117
|
-
pip install tox-gh-actions
|
147
|
+
python -m pip install tox-gh-actions
|
118
148
|
|
119
149
|
# Run the test suite
|
120
150
|
- name: Run the tests
|
121
151
|
env:
|
122
|
-
SPATIALITE_LIBRARY_PATH: /
|
123
|
-
PROJ_LIB: /home/runner/micromamba/envs/test_${{ matrix.python-version.flag }}/share/proj
|
152
|
+
SPATIALITE_LIBRARY_PATH: /usr/lib/x86_64-linux-gnu/mod_spatialite.so
|
124
153
|
COVERAGE_FILE: .coverage
|
125
|
-
PYTEST_MYSQL_DB_URL: mysql://gis:gis@127.0.0.1/gis
|
154
|
+
PYTEST_MYSQL_DB_URL: mysql://gis:gis@127.0.0.1:3307/gis
|
155
|
+
PYTEST_MARIADB_DB_URL: mariadb://gis:gis@127.0.0.1:3308/gis
|
126
156
|
run: |
|
157
|
+
if [[ ${{ matrix.python-version.flag }} == 'pypy3.10' ]]; then
|
158
|
+
export PYTEST_ADDOPTS=${PYTEST_ADDOPTS}' --ignore=tests/gallery/test_insert_raster.py'
|
159
|
+
export PYTEST_SPATIALITE3_DB_URL="FAILING URL"
|
160
|
+
export PYTEST_SPATIALITE4_DB_URL="FAILING URL"
|
161
|
+
else
|
162
|
+
export PYTEST_ADDOPTS='--require-all-dialects'
|
163
|
+
fi;
|
127
164
|
# Run the unit test suite with SQLAlchemy=1.4.* and then with the latest version of SQLAlchemy
|
128
165
|
tox -vv
|
129
166
|
|
@@ -1,8 +1,6 @@
|
|
1
|
-
default_language_version:
|
2
|
-
python: python3.8
|
3
1
|
repos:
|
4
2
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
5
|
-
rev:
|
3
|
+
rev: v5.0.0
|
6
4
|
hooks:
|
7
5
|
- id: check-added-large-files
|
8
6
|
- id: check-case-conflict
|
@@ -17,7 +15,7 @@ repos:
|
|
17
15
|
hooks:
|
18
16
|
- id: isort
|
19
17
|
- repo: https://github.com/psf/black
|
20
|
-
rev: 24.
|
18
|
+
rev: 24.10.0
|
21
19
|
hooks:
|
22
20
|
- id: black
|
23
21
|
- repo: https://github.com/codespell-project/codespell
|
@@ -31,7 +29,7 @@ repos:
|
|
31
29
|
additional_dependencies: ["tomli"]
|
32
30
|
exclude: "tests"
|
33
31
|
- repo: https://github.com/PyCQA/flake8
|
34
|
-
rev: 7.1.
|
32
|
+
rev: 7.1.1
|
35
33
|
hooks:
|
36
34
|
- id: flake8
|
37
35
|
ci:
|
@@ -1,6 +1,20 @@
|
|
1
1
|
GeoAlchemy 2 Changelog
|
2
2
|
======================
|
3
3
|
|
4
|
+
0.17.0
|
5
|
+
------
|
6
|
+
|
7
|
+
* Perf: Enable cache for all types of GeoAlchemy2 @adrien-berchet (#525)
|
8
|
+
* Feat: Add new plugin to automatically attach events based on the engine dialect @adrien-berchet (#525)
|
9
|
+
* CI: Disable SQLite for Pypy job @adrien-berchet (#528)
|
10
|
+
|
11
|
+
0.16.0
|
12
|
+
------
|
13
|
+
|
14
|
+
* Test: Add test in test_functional.py for custom Geometry that uses WKT elements @adrien-berchet (#525)
|
15
|
+
* Add option to ensure all dialects are properly tested in CI @adrien-berchet (#526)
|
16
|
+
* Improve MariaDB support @adrien-berchet (#524)
|
17
|
+
|
4
18
|
0.15.2
|
5
19
|
------
|
6
20
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: GeoAlchemy2
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.17.0
|
4
4
|
Summary: Using SQLAlchemy with Spatial Databases
|
5
5
|
Home-page: https://geoalchemy-2.readthedocs.io/en/stable/
|
6
6
|
Author: Eric Lemoine
|
@@ -28,6 +28,18 @@ Requires-Dist: SQLAlchemy>=1.4
|
|
28
28
|
Requires-Dist: packaging
|
29
29
|
Provides-Extra: shapely
|
30
30
|
Requires-Dist: Shapely>=1.7; extra == "shapely"
|
31
|
+
Dynamic: author
|
32
|
+
Dynamic: author-email
|
33
|
+
Dynamic: classifier
|
34
|
+
Dynamic: description
|
35
|
+
Dynamic: home-page
|
36
|
+
Dynamic: keywords
|
37
|
+
Dynamic: license
|
38
|
+
Dynamic: project-url
|
39
|
+
Dynamic: provides-extra
|
40
|
+
Dynamic: requires-dist
|
41
|
+
Dynamic: requires-python
|
42
|
+
Dynamic: summary
|
31
43
|
|
32
44
|
============
|
33
45
|
GeoAlchemy 2
|
@@ -29,6 +29,7 @@ tox.ini
|
|
29
29
|
GeoAlchemy2.egg-info/PKG-INFO
|
30
30
|
GeoAlchemy2.egg-info/SOURCES.txt
|
31
31
|
GeoAlchemy2.egg-info/dependency_links.txt
|
32
|
+
GeoAlchemy2.egg-info/entry_points.txt
|
32
33
|
GeoAlchemy2.egg-info/not-zip-safe
|
33
34
|
GeoAlchemy2.egg-info/requires.txt
|
34
35
|
GeoAlchemy2.egg-info/top_level.txt
|
@@ -39,15 +40,18 @@ doc/alembic_helpers.rst
|
|
39
40
|
doc/changelog.rst
|
40
41
|
doc/conf.py
|
41
42
|
doc/core_tutorial.rst
|
43
|
+
doc/dialect_specific_features.rst
|
42
44
|
doc/elements.rst
|
43
45
|
doc/index.rst
|
44
46
|
doc/make.bat
|
45
47
|
doc/migrate.rst
|
48
|
+
doc/mysql_mariadb_dialect.rst
|
46
49
|
doc/orm_tutorial.rst
|
50
|
+
doc/plugin.rst
|
47
51
|
doc/shape.rst
|
48
52
|
doc/spatial_functions.rst
|
49
53
|
doc/spatial_operators.rst
|
50
|
-
doc/
|
54
|
+
doc/spatialite_dialect.rst
|
51
55
|
doc/types.rst
|
52
56
|
doc/_static/geoalchemy.png
|
53
57
|
doc/_static/geoalchemy.svg
|
@@ -76,9 +80,11 @@ geoalchemy2/py.typed
|
|
76
80
|
geoalchemy2/shape.py
|
77
81
|
geoalchemy2/utils.py
|
78
82
|
geoalchemy2/admin/__init__.py
|
83
|
+
geoalchemy2/admin/plugin.py
|
79
84
|
geoalchemy2/admin/dialects/__init__.py
|
80
85
|
geoalchemy2/admin/dialects/common.py
|
81
86
|
geoalchemy2/admin/dialects/geopackage.py
|
87
|
+
geoalchemy2/admin/dialects/mariadb.py
|
82
88
|
geoalchemy2/admin/dialects/mysql.py
|
83
89
|
geoalchemy2/admin/dialects/postgresql.py
|
84
90
|
geoalchemy2/admin/dialects/sqlite.py
|
@@ -86,15 +92,20 @@ geoalchemy2/types/__init__.py
|
|
86
92
|
geoalchemy2/types/dialects/__init__.py
|
87
93
|
geoalchemy2/types/dialects/common.py
|
88
94
|
geoalchemy2/types/dialects/geopackage.py
|
95
|
+
geoalchemy2/types/dialects/mariadb.py
|
89
96
|
geoalchemy2/types/dialects/mysql.py
|
90
97
|
geoalchemy2/types/dialects/postgresql.py
|
91
98
|
geoalchemy2/types/dialects/sqlite.py
|
92
99
|
test_container/.dockerignore
|
93
100
|
test_container/.gitignore
|
94
101
|
test_container/Dockerfile
|
102
|
+
test_container/Dockerfile_mariadb
|
95
103
|
test_container/build.sh
|
104
|
+
test_container/build_mariadb.sh
|
96
105
|
test_container/run.sh
|
106
|
+
test_container/run_mariadb.sh
|
97
107
|
test_container/helpers/entrypoint.sh
|
108
|
+
test_container/helpers/init_mariadb.sh
|
98
109
|
test_container/helpers/init_mysql.sh
|
99
110
|
test_container/helpers/init_postgres.sh
|
100
111
|
test_container/helpers/install_requirements.sh
|
@@ -111,6 +122,7 @@ tests/test_functional_postgresql.py
|
|
111
122
|
tests/test_functional_sqlite.py
|
112
123
|
tests/test_functions.py
|
113
124
|
tests/test_pickle.py
|
125
|
+
tests/test_plugin.py
|
114
126
|
tests/test_shape.py
|
115
127
|
tests/test_types.py
|
116
128
|
tests/alembic_config/alembic.ini
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: GeoAlchemy2
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.17.0
|
4
4
|
Summary: Using SQLAlchemy with Spatial Databases
|
5
5
|
Home-page: https://geoalchemy-2.readthedocs.io/en/stable/
|
6
6
|
Author: Eric Lemoine
|
@@ -28,6 +28,18 @@ Requires-Dist: SQLAlchemy>=1.4
|
|
28
28
|
Requires-Dist: packaging
|
29
29
|
Provides-Extra: shapely
|
30
30
|
Requires-Dist: Shapely>=1.7; extra == "shapely"
|
31
|
+
Dynamic: author
|
32
|
+
Dynamic: author-email
|
33
|
+
Dynamic: classifier
|
34
|
+
Dynamic: description
|
35
|
+
Dynamic: home-page
|
36
|
+
Dynamic: keywords
|
37
|
+
Dynamic: license
|
38
|
+
Dynamic: project-url
|
39
|
+
Dynamic: provides-extra
|
40
|
+
Dynamic: requires-dist
|
41
|
+
Dynamic: requires-python
|
42
|
+
Dynamic: summary
|
31
43
|
|
32
44
|
============
|
33
45
|
GeoAlchemy 2
|
@@ -25,16 +25,21 @@ PostgreSQL-specific objects
|
|
25
25
|
:private-members:
|
26
26
|
:show-inheritance:
|
27
27
|
|
28
|
-
MySQL-specific objects
|
29
|
-
|
28
|
+
MySQL/MariadDB-specific objects
|
29
|
+
-------------------------------
|
30
30
|
|
31
31
|
.. automodule:: geoalchemy2.admin.dialects.mysql
|
32
32
|
:members:
|
33
33
|
:private-members:
|
34
34
|
:show-inheritance:
|
35
35
|
|
36
|
+
.. automodule:: geoalchemy2.admin.dialects.mariadb
|
37
|
+
:members:
|
38
|
+
:private-members:
|
39
|
+
:show-inheritance:
|
40
|
+
|
36
41
|
SQLite-specific objects
|
37
|
-
|
42
|
+
-----------------------
|
38
43
|
|
39
44
|
.. automodule:: geoalchemy2.admin.dialects.sqlite
|
40
45
|
:members:
|
@@ -21,7 +21,11 @@ For this tutorial we will use a PostGIS 2 database. To connect we use
|
|
21
21
|
SQLAlchemy's ``create_engine()`` function::
|
22
22
|
|
23
23
|
>>> from sqlalchemy import create_engine
|
24
|
-
>>> engine = create_engine(
|
24
|
+
>>> engine = create_engine(
|
25
|
+
... 'postgresql://gis:gis@localhost/gis',
|
26
|
+
... echo=True,
|
27
|
+
... plugins=["geoalchemy2"],
|
28
|
+
... )
|
25
29
|
|
26
30
|
In this example the name of the database, the database user, and the database
|
27
31
|
password, is ``gis``.
|
@@ -30,6 +34,11 @@ The ``echo`` flag is a shortcut to setting up SQLAlchemy logging, which is
|
|
30
34
|
accomplished via Python's standard logging module. With it is enabled, we'll
|
31
35
|
see all the generated SQL produced.
|
32
36
|
|
37
|
+
The ``plugins`` argument adds some event listeners to adapt the behavior of
|
38
|
+
``GeoAlchemy2`` to the dialect. This is not mandatory but if the plugin is not
|
39
|
+
loaded, then the listeners will have to be added to the engine manually (see an
|
40
|
+
example in :ref:`spatialite_dialect`).
|
41
|
+
|
33
42
|
The return value of ``create_engine`` is an ``Engine`` object, which
|
34
43
|
represents the core interface to the database.
|
35
44
|
|
@@ -84,7 +93,10 @@ be registered into SQLAlchemy, even if it is not used explicitly.
|
|
84
93
|
|
85
94
|
>>> from geoalchemy2 import Geometry # <= not used but must be imported
|
86
95
|
>>> from sqlalchemy import create_engine, MetaData
|
87
|
-
>>> engine = create_engine(
|
96
|
+
>>> engine = create_engine(
|
97
|
+
... "postgresql://myuser:mypass@mydb.host.tld/mydbname",
|
98
|
+
... plugins=["geoalchemy2"]
|
99
|
+
... )
|
88
100
|
>>> meta = MetaData()
|
89
101
|
>>> meta.reflect(bind=engine)
|
90
102
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
.. _dialect_specific_features:
|
2
|
+
|
3
|
+
Dialect specific features
|
4
|
+
=========================
|
5
|
+
|
6
|
+
Several dialects handle spatial data in different ways. ``GeoAlchemy2`` tries to hide these
|
7
|
+
differences but sometimes manual tweaks are needed.
|
8
|
+
|
9
|
+
.. toctree::
|
10
|
+
:maxdepth: 1
|
11
|
+
|
12
|
+
mysql_mariadb_dialect
|
13
|
+
spatialite_dialect
|
@@ -17,7 +17,7 @@ GeoAlchemy 2 also supports the following dialects:
|
|
17
17
|
* `GeoPackage <http://www.geopackage.org/spec/>`_
|
18
18
|
|
19
19
|
Note that using GeoAlchemy 2 with these dialects may require some specific configuration on the
|
20
|
-
application side.
|
20
|
+
application side. It also may not be optimal for performance.
|
21
21
|
|
22
22
|
GeoAlchemy 2 aims to be simpler than its predecessor, `GeoAlchemy
|
23
23
|
<https://pypi.python.org/pypi/GeoAlchemy>`_. Simpler to use, and simpler
|
@@ -87,7 +87,7 @@ system. If you're new to GeoAlchemy 2 start with this.
|
|
87
87
|
|
88
88
|
orm_tutorial
|
89
89
|
core_tutorial
|
90
|
-
|
90
|
+
dialect_specific_features
|
91
91
|
|
92
92
|
|
93
93
|
Gallery
|
@@ -121,6 +121,7 @@ Reference Documentation
|
|
121
121
|
:maxdepth: 1
|
122
122
|
|
123
123
|
admin
|
124
|
+
plugin
|
124
125
|
types
|
125
126
|
elements
|
126
127
|
spatial_functions
|
@@ -133,10 +134,14 @@ Development
|
|
133
134
|
|
134
135
|
The code is available on GitHub: https://github.com/geoalchemy/geoalchemy2.
|
135
136
|
|
136
|
-
|
137
|
+
Main authors:
|
137
138
|
|
138
139
|
* Adrien Berchet (https://github.com/adrien-berchet)
|
139
140
|
* Éric Lemoine (https://github.com/elemoine)
|
141
|
+
|
142
|
+
Other contributors:
|
143
|
+
|
144
|
+
* Caleb Johnson (https://github.com/calebj)
|
140
145
|
* Dolf Andringa (https://github.com/dolfandringa)
|
141
146
|
* Frédéric Junod, Camptocamp SA (https://github.com/fredj)
|
142
147
|
* ijl (https://github.com/ijl)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.. _mysql_mariadb_dialect:
|
2
|
+
|
3
|
+
MySQL / MariaDB Tutorial
|
4
|
+
========================
|
5
|
+
|
6
|
+
GeoAlchemy 2's main target is PostGIS. But GeoAlchemy 2 also supports MySQL and MariaDB.
|
7
|
+
This tutorial describes how to use GeoAlchemy 2 with these dialects.
|
8
|
+
|
9
|
+
.. _mysql_mariadb_connect:
|
10
|
+
|
11
|
+
Connect to the DB
|
12
|
+
-----------------
|
13
|
+
|
14
|
+
Just like when using PostGIS connecting to a MySQL or MariaDB database requires an ``Engine``.
|
15
|
+
An engine for these dialects can be created in two ways. Using the plugin provided by
|
16
|
+
``GeoAlchemy2`` (see :ref:`plugin` for more details)::
|
17
|
+
|
18
|
+
>>> from sqlalchemy import create_engine
|
19
|
+
>>> engine = create_engine(
|
20
|
+
... "mysql://user:password@host:port/dbname",
|
21
|
+
... echo=True,
|
22
|
+
... plugins=["geoalchemy2"]
|
23
|
+
... )
|
24
|
+
|
25
|
+
The call to ``create_engine`` creates an engine bound to the database given in the URL. After that
|
26
|
+
a ``before_cursor_execute`` listener is registered on the engine (see
|
27
|
+
:func:`geoalchemy2.admin.dialects.mysql.before_cursor_execute` and
|
28
|
+
:func:`geoalchemy2.admin.dialects.mariadb.before_cursor_execute`). The listener is responsible for
|
29
|
+
converting the parameters passed to query in the proper format, which is often a necessary operation
|
30
|
+
for using these dialects, though it depends on the driver used. If the driver does not require such
|
31
|
+
conversion, it is possible to disable this feature with the URL parameter
|
32
|
+
``geoalchemy2_before_cursor_execute_mysql_convert`` or
|
33
|
+
``geoalchemy2_before_cursor_execute_mariadb_convert``, depending on the dialect used.
|
34
|
+
|
35
|
+
|
36
|
+
It is also possible to create a raw engine and attach the listener manually::
|
37
|
+
|
38
|
+
>>> from geoalchemy2.admin.dialects.mysql import before_cursor_execute
|
39
|
+
>>> from sqlalchemy import create_engine
|
40
|
+
>>> from sqlalchemy.event import listen
|
41
|
+
>>>
|
42
|
+
>>> engine = create_engine("mysql://user:password@host:port/dbname", echo=True)
|
43
|
+
>>> listen(engine, "before_cursor_execute", before_cursor_execute)
|
@@ -20,7 +20,11 @@ For this tutorial we will use a PostGIS 2 database. To connect we use
|
|
20
20
|
SQLAlchemy's ``create_engine()`` function::
|
21
21
|
|
22
22
|
>>> from sqlalchemy import create_engine
|
23
|
-
>>> engine = create_engine(
|
23
|
+
>>> engine = create_engine(
|
24
|
+
... 'postgresql://gis:gis@localhost/gis',
|
25
|
+
... echo=True,
|
26
|
+
... plugins=["geoalchemy2"]
|
27
|
+
... )
|
24
28
|
|
25
29
|
In this example the name of the database, the database user, and the database
|
26
30
|
password, is ``gis``.
|
@@ -29,6 +33,11 @@ The ``echo`` flag is a shortcut to setting up SQLAlchemy logging, which is
|
|
29
33
|
accomplished via Python's standard logging module. With it is enabled, we'll
|
30
34
|
see all the generated SQL produced.
|
31
35
|
|
36
|
+
The ``plugins`` argument adds some event listeners to adapt the behavior of
|
37
|
+
``GeoAlchemy2`` to the dialect. This is not mandatory but if the plugin is not
|
38
|
+
loaded, then the listeners will have to be added to the engine manually (see an
|
39
|
+
example in :ref:`spatialite_dialect`).
|
40
|
+
|
32
41
|
The return value of ``create_engine`` is an ``Engine`` object, which
|
33
42
|
represents the core interface to the database.
|
34
43
|
|
@@ -128,7 +137,9 @@ Add New Objects
|
|
128
137
|
|
129
138
|
To persist our ``Lake`` object, we ``add()`` it to the ``Session``::
|
130
139
|
|
140
|
+
>>> lake = Lake(name="Majeur", geom="POLYGON((0 0,1 0,1 1,0 1,0 0))")
|
131
141
|
>>> session.add(lake)
|
142
|
+
>>> session.commit()
|
132
143
|
|
133
144
|
At this point the ``lake`` object has been added to the ``Session``, but no SQL
|
134
145
|
has been issued to the database. The object is in a *pending* state. To persist
|
@@ -237,6 +248,9 @@ We can also apply relationship functions to
|
|
237
248
|
``session.scalar`` allows executing a clause and returning a scalar
|
238
249
|
value (a boolean value in this case).
|
239
250
|
|
251
|
+
The value ``True`` indicates that the lake "Garde" does intersects the ``LINESTRING(2 1,4 1)``
|
252
|
+
geometry. See the SpatiaLite SQL functions reference list for more information.
|
253
|
+
|
240
254
|
The GeoAlchemy functions all start with ``ST_``. Operators are also called as
|
241
255
|
functions, but the function names don't include the ``ST_`` prefix. As an
|
242
256
|
example let's use PostGIS' ``&&`` operator, which allows testing
|
geoalchemy2-0.15.2/doc/spatialite_tutorial.rst → geoalchemy2-0.17.0/doc/spatialite_dialect.rst
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
..
|
1
|
+
.. _spatialite_dialect:
|
2
2
|
|
3
3
|
SpatiaLite Tutorial
|
4
4
|
===================
|
@@ -12,8 +12,18 @@ the :ref:`orm_tutorial`, which you may want to read first.
|
|
12
12
|
Connect to the DB
|
13
13
|
-----------------
|
14
14
|
|
15
|
-
Just like when using PostGIS connecting to a SpatiaLite database requires an ``Engine``.
|
16
|
-
|
15
|
+
Just like when using PostGIS connecting to a SpatiaLite database requires an ``Engine``. An engine
|
16
|
+
for the SpatiaLite dialect can be created in two ways. Using the plugin provided by
|
17
|
+
``GeoAlchemy2`` (see :ref:`plugin` for more details)::
|
18
|
+
|
19
|
+
>>> from sqlalchemy import create_engine
|
20
|
+
>>> engine = create_engine(
|
21
|
+
... "sqlite:///gis.db",
|
22
|
+
... echo=True,
|
23
|
+
... plugins=["geoalchemy2"]
|
24
|
+
... )
|
25
|
+
|
26
|
+
Or by attaching the listeners manually::
|
17
27
|
|
18
28
|
>>> from geoalchemy2 import load_spatialite
|
19
29
|
>>> from sqlalchemy import create_engine
|
@@ -70,108 +80,6 @@ From the user point of view this works in the same way as with PostGIS. The diff
|
|
70
80
|
internally the ``RecoverGeometryColumn`` and ``DiscardGeometryColumn`` management functions will be
|
71
81
|
used for the creation and removal of the geometry column.
|
72
82
|
|
73
|
-
Create the Table in the Database
|
74
|
-
--------------------------------
|
75
|
-
|
76
|
-
We can now create the ``lake`` table in the ``gis.db`` database::
|
77
|
-
|
78
|
-
>>> Lake.__table__.create(engine)
|
79
|
-
|
80
|
-
If we wanted to drop the table we'd use::
|
81
|
-
|
82
|
-
>>> Lake.__table__.drop(engine)
|
83
|
-
|
84
|
-
There's nothing specific to SpatiaLite here.
|
85
|
-
|
86
|
-
Create a Session
|
87
|
-
----------------
|
88
|
-
|
89
|
-
When using the SQLAlchemy ORM the ORM interacts with the database through a ``Session``.
|
90
|
-
|
91
|
-
>>> from sqlalchemy.orm import sessionmaker
|
92
|
-
>>> Session = sessionmaker(bind=engine)
|
93
|
-
>>> session = Session()
|
94
|
-
|
95
|
-
The session is associated with our SpatiaLite ``Engine``. Again, there's nothing
|
96
|
-
specific to SpatiaLite here.
|
97
|
-
|
98
|
-
Add New Objects
|
99
|
-
---------------
|
100
|
-
|
101
|
-
We can now create and insert new ``Lake`` objects into the database, the same way we'd
|
102
|
-
do it using GeoAlchemy 2 with PostGIS.
|
103
|
-
|
104
|
-
::
|
105
|
-
|
106
|
-
>>> lake = Lake(name="Majeur", geom="POLYGON((0 0,1 0,1 1,0 1,0 0))")
|
107
|
-
>>> session.add(lake)
|
108
|
-
>>> session.commit()
|
109
|
-
|
110
|
-
We can now query the database for ``Majeur``::
|
111
|
-
|
112
|
-
>>> our_lake = session.query(Lake).filter_by(name="Majeur").first()
|
113
|
-
>>> our_lake.name
|
114
|
-
u"Majeur"
|
115
|
-
>>> our_lake.geom
|
116
|
-
<WKBElement at 0x9af594c; "0103000000010000000500000000000000000000000000000000000000000000000000f03f0000000000000000000000000000f03f000000000000f03f0000000000000000000000000000f03f00000000000000000000000000000000">
|
117
|
-
>>> our_lake.id
|
118
|
-
1
|
119
|
-
|
120
|
-
Let's add more lakes::
|
121
|
-
|
122
|
-
>>> session.add_all([
|
123
|
-
... Lake(name="Garde", geom="POLYGON((1 0,3 0,3 2,1 2,1 0))"),
|
124
|
-
... Lake(name="Orta", geom="POLYGON((3 0,6 0,6 3,3 3,3 0))")
|
125
|
-
... ])
|
126
|
-
>>> session.commit()
|
127
|
-
|
128
|
-
Query
|
129
|
-
-----
|
130
|
-
|
131
|
-
Let's make a simple, non-spatial, query::
|
132
|
-
|
133
|
-
>>> query = session.query(Lake).order_by(Lake.name)
|
134
|
-
>>> for lake in query:
|
135
|
-
... print(lake.name)
|
136
|
-
...
|
137
|
-
Garde
|
138
|
-
Majeur
|
139
|
-
Orta
|
140
|
-
|
141
|
-
Now a spatial query::
|
142
|
-
|
143
|
-
>>> from geolachemy2 import WKTElement
|
144
|
-
>>> query = session.query(Lake).filter(
|
145
|
-
... func.ST_Contains(Lake.geom, WKTElement("POINT(4 1)")))
|
146
|
-
...
|
147
|
-
>>> for lake in query:
|
148
|
-
... print(lake.name)
|
149
|
-
...
|
150
|
-
Orta
|
151
|
-
|
152
|
-
Here's another spatial query, using ``ST_Intersects`` this time::
|
153
|
-
|
154
|
-
>>> query = session.query(Lake).filter(
|
155
|
-
... Lake.geom.ST_Intersects(WKTElement("LINESTRING(2 1,4 1)")))
|
156
|
-
...
|
157
|
-
>>> for lake in query:
|
158
|
-
... print(lake.name)
|
159
|
-
...
|
160
|
-
Garde
|
161
|
-
Orta
|
162
|
-
|
163
|
-
We can also apply relationship functions to :class:`geoalchemy2.elements.WKBElement`. For example::
|
164
|
-
|
165
|
-
>>> lake = session.query(Lake).filter_by(name="Garde").one()
|
166
|
-
>>> print(session.scalar(lake.geom.ST_Intersects(WKTElement("LINESTRING(2 1,4 1)"))))
|
167
|
-
1
|
168
|
-
|
169
|
-
``session.scalar`` allows executing a clause and returning a scalar value (an integer value in this
|
170
|
-
case).
|
171
|
-
|
172
|
-
The value ``1`` indicates that the lake "Garde" does intersects the ``LINESTRING(2 1,4 1)``
|
173
|
-
geometry. See the SpatiaLite SQL functions reference list for more information.
|
174
|
-
|
175
83
|
Function mapping
|
176
84
|
----------------
|
177
85
|
|
@@ -201,7 +109,7 @@ GeoPackage format
|
|
201
109
|
Starting from the version ``4.2`` of Spatialite, it is possible to use GeoPackage files as DB
|
202
110
|
containers. GeoAlchemy 2 is able to handle most of the GeoPackage features automatically if the
|
203
111
|
GeoPackage dialect is used (i.e. the DB URL starts with ``gpkg:///``) and the SpatiaLite extension
|
204
|
-
is loaded. Usually, this extension should be loaded using the ``load_spatialite_gpkg`` listener::
|
112
|
+
is loaded. Usually, this extension should be loaded using the the ``GeoAlchemy2`` plugin (see :ref:`connect <spatialite_connect>` section) or by attaching the ``load_spatialite_gpkg`` listener to the engine::
|
205
113
|
|
206
114
|
>>> from geoalchemy2 import load_spatialite_gpkg
|
207
115
|
>>> from sqlalchemy import create_engine
|