Python 地球炼金术2&;点和多边形之间的ST_in-type不匹配?

Python 地球炼金术2&;点和多边形之间的ST_in-type不匹配?,python,postgresql,sqlalchemy,postgis,geoalchemy2,Python,Postgresql,Sqlalchemy,Postgis,Geoalchemy2,我想运行一个查询,返回矩形中的每个点,其中点和矩形基于真实世界的经度和纬度 这是失败的查询: results = session.query(Store.id).filter(func.ST_Within(Store.location, func.ST_GeomFromEWKT('SRID=4326;POLYGON((150 -33, 152 -33, 152 -31, 150 -31, 150 -33))'))) 它毫无怨言地运行,但在调用results.first()时,我看到以下错误和警

我想运行一个查询,返回矩形中的每个点,其中点和矩形基于真实世界的经度和纬度

这是失败的查询:

results = session.query(Store.id).filter(func.ST_Within(Store.location, func.ST_GeomFromEWKT('SRID=4326;POLYGON((150 -33, 152 -33, 152 -31, 150 -31, 150 -33))')))
它毫无怨言地运行,但在调用results.first()时,我看到以下错误和警告:

sqlalchemy.exc.ProgrammingError:(psycopg2.ProgrammingError)中的函数st_(地理、几何)不存在 第3行:其中ST_在(store.location,ST_geomefromewkt('SRID=4326;P。。。 ^ 提示:没有与给定名称和参数类型匹配的函数。您可能需要添加显式类型转换。 [SQL:'选择store.id作为store\u id\n从store\n中选择(store.location,ST_geomefromewkt(%(ST_geomefromewkt)s ))\n LIMIT%(param_1)s'][参数:{'ST_geomefromewkt_1':'SRID=4326;多边形((150-33152-33152-31150-31150 -33)),“参数1”:1}]

但是,我可以通过在查询中创建一个伪点(使每个存储都匹配)使查询工作:

这表明问题出在我的Store.location字段上,但我尝试过的[包括type_强制(Store.location,geography)]都不起作用

这是我对location列的SQLAlchemy定义:

location = Column(Geography(geometry_type='POINT', srid=4326))
这是我运行的将经度和纬度转换为位置的代码(我还尝试使用func.ST_geomefromewkt()强制该类型):

Python告诉我Store.location的类型是“geoalchemy2.elements.WKBElement”,这是我在文档中所期望的

请问有没有人对如何解决这个问题有什么建议

仅供参考,我正在运行:

  • PostgreSQL 9.6.1
  • psycopg2 2.6.2
  • SQLAlchemy 1.1.4和
  • 地球炼金术2 0.4.0

多亏了其他人(迈克·拜耳和格雷格·贝克)的帮助,我可以发布答案

问题是:

  • 我的点是地理类型,多边形是几何类型
  • 许多其他PostGIS功能,包括ST_在内,不支持地理位置(即,它们只支持几何图形)
  • 答案是在查询中将地理强制转换为几何体。以下查询有效:

    results = session.query(Store.id).filter(func.ST_Within(cast(Store.location, Geometry), func.ST_GeomFromEWKT('SRID=4326;POLYGON((150 -33, 152 -33, 152 -31, 150 -31, 150 -33))')))
    
    stores = session.query(Store)
    for store in stores:
        store.location = 'SRID=4326;POINT({} {})'.format(store.longitude, store.latitude)
    session.commit()
    
    results = session.query(Store.id).filter(func.ST_Within(cast(Store.location, Geometry), func.ST_GeomFromEWKT('SRID=4326;POLYGON((150 -33, 152 -33, 152 -31, 150 -31, 150 -33))')))