使用CompositeType

某些函数返回复合类型。这个例子展示了如何处理这类函数。

  8 from sqlalchemy import Column
  9 from sqlalchemy import create_engine
 10 from sqlalchemy import Float
 11 from sqlalchemy import func
 12 from sqlalchemy import Integer
 13 from sqlalchemy import MetaData
 14 from sqlalchemy import select
 15 from sqlalchemy.ext.declarative import declarative_base
 16 from sqlalchemy.orm import sessionmaker
 17
 18 from geoalchemy2 import Raster, WKTElement
 19 from geoalchemy2.functions import GenericFunction
 20 from geoalchemy2.types import CompositeType
 21
 22
 23 class SummaryStats(CompositeType):
 24     """Define the composite type returned by the function ST_SummaryStatsAgg"""
 25     typemap = {
 26         'count': Integer,
 27         'sum': Float,
 28         'mean': Float,
 29         'stddev': Float,
 30         'min': Float,
 31         'max': Float,
 32     }
 33
 34
 35 class ST_SummaryStatsAgg(GenericFunction):
 36     type = SummaryStats
 37
 38
 39 engine = create_engine('postgresql://gis:gis@localhost/gis', echo=True)
 40 metadata = MetaData(engine)
 41 Base = declarative_base(metadata=metadata)
 42 session = sessionmaker(bind=engine)()
 43
 44
 45 class Ocean(Base):
 46     __tablename__ = 'ocean'
 47     __table_args__ = {'schema': 'public'}
 48     id = Column(Integer, primary_key=True)
 49     rast = Column(Raster)
 50
 51     def __init__(self, rast):
 52         self.rast = rast
 53
 54
 55 class TestSTSummaryStatsAgg():
 56
 57     def setup(self):
 58         metadata.drop_all(checkfirst=True)
 59         metadata.create_all()
 60
 61     def teardown(self):
 62         session.rollback()
 63         metadata.drop_all()
 64
 65     def test_st_summary_stats_agg(self):
 66
 67         # Create a new raster
 68         polygon = WKTElement('POLYGON((0 0,1 1,0 1,0 0))', srid=4326)
 69         o = Ocean(polygon.ST_AsRaster(5, 6))
 70         session.add(o)
 71         session.flush()
 72
 73         # Define the query to compute stats
 74         stats_agg = select([
 75             func.ST_SummaryStatsAgg(Ocean.__table__.c.rast, 1, True, 1).label("stats")
 76         ])
 77         stats_agg_alias = stats_agg.alias("stats_agg")
 78
 79         # Use these stats
 80         query = select([
 81             stats_agg_alias.c.stats.count.label("count"),
 82             stats_agg_alias.c.stats.sum.label("sum"),
 83             stats_agg_alias.c.stats.stddev.label("stddev"),
 84             stats_agg_alias.c.stats.min.label("min"),
 85             stats_agg_alias.c.stats.max.label("max")
 86         ])
 87
 88         # Check the query
 89         assert str(query) == (
 90             "SELECT "
 91             "(stats_agg.stats).count AS count, "
 92             "(stats_agg.stats).sum AS sum, "
 93             "(stats_agg.stats).stddev AS stddev, "
 94             "(stats_agg.stats).min AS min, "
 95             "(stats_agg.stats).max AS max \n"
 96             "FROM ("
 97             "SELECT "
 98             "ST_SummaryStatsAgg("
 99             "public.ocean.rast, "
100             "%(ST_SummaryStatsAgg_1)s, %(ST_SummaryStatsAgg_2)s, %(ST_SummaryStatsAgg_3)s"
101             ") AS stats \n"
102             "FROM public.ocean) AS stats_agg"
103         )
104
105         # Execute the query
106         res = session.execute(query).fetchall()
107
108         # Check the result
109         assert res == [(15, 15.0, 0.0, 1.0, 1.0)]

脚本的总运行时间: (0分0.000秒)

Gallery generated by Sphinx-Gallery