New ORM Declarative Mapping StyleΒΆ

SQLAlchemy>=2 introduced a new way to construct mappings using the sqlalchemy.orm.DeclarativeBase base class. This example shows how to use GeoAlchemy2 types in this context.

10 import pytest
11 from packaging.version import parse as parse_version
12 from sqlalchemy import __version__ as SA_VERSION
13
14 try:
15     from sqlalchemy.orm import DeclarativeBase
16     from sqlalchemy.orm import Mapped
17     from sqlalchemy.orm import mapped_column
18 except ImportError:
19     pass
20
21 from geoalchemy2 import Geometry
22 from geoalchemy2 import WKBElement
23 from geoalchemy2 import shape
24
25
26 def check_wkb(wkb, x, y) -> None:
27     pt = shape.to_shape(wkb)
28     assert round(pt.x, 5) == x
29     assert round(pt.y, 5) == y
30
31
32 @pytest.mark.skipif(
33     parse_version(SA_VERSION) < parse_version("2"),
34     reason="New ORM mapping is only available for sqlalchemy>=2",
35 )
36 def test_ORM_mapping(session, conn, schema) -> None:
37     class Base(DeclarativeBase):
38         pass
39
40     class Lake(Base):
41         __tablename__ = "lake"
42         __table_args__ = {"schema": schema}
43         id: Mapped[int] = mapped_column(primary_key=True)
44         mapped_geom: Mapped[WKBElement] = mapped_column(Geometry(geometry_type="POINT", srid=4326))
45
46     Lake.__table__.drop(conn, checkfirst=True)  # type: ignore[attr-defined]
47     Lake.__table__.create(bind=conn)  # type: ignore[attr-defined]
48
49     # Create new point instance
50     p = Lake()
51     p.mapped_geom = "SRID=4326;POINT(5 45)"  # type: ignore[assignment]
52
53     # Insert point
54     session.add(p)
55     session.flush()
56     session.expire(p)
57
58     # Query the point and check the result
59     pt = session.query(Lake).one()
60     assert pt.id == 1
61     assert pt.mapped_geom.srid == 4326
62     check_wkb(pt.mapped_geom, 5, 45)

Gallery generated by Sphinx-Gallery