我有一个名为tasks
的postgis数据库表,使用geoalchemy2 / sqlalchemy映射到python类Task
- 每个条目都有一个MultiPolygon geometry
和一个整数state
。总的来说,我的数据库中的条目涵盖了一个地理区域。我想选择state = 0的随机条目,该条目在地理上不与state = 1 的任何条目相邻。
这是选择state = 0的随机条目的代码:
class Task(Base):
__tablename__ = "tasks"
id = Column(Integer, primary_key=True, index=True)
geometry = Column(Geometry('MultiPolygon', srid=4326))
state = Column(Integer, default=0)
session = DBSession()
taskgetter = session.query(Task).filter_by(state=0)
count = taskgetter.count()
if count != 0:
atask = taskgetter.offset(random.randint(0, count-1)).first()
到目前为止一切顺利。但现在,如何确保它们不与另一组条目相邻?
Geoalchemy有一个函数ST_Union可以统一几何,而ST_Disjoint可以检测它们是否相交。所以似乎我应该能够选择状态= 1的项目,将它们合并为一个几何体,然后过滤掉我的原始查询(上面)以仅保留与它不相交的项目。但我找不到在地质考试中表达这种方法的方法。这是我试过的一种方式:
session = DBSession()
taskgetter = session.query(Task).filter_by(state=0) \
.filter(Task.geometry.ST_Disjoint(session.query( \
Task.geometry.ST_Union()).filter_by(state=1)))
count = taskgetter.count()
if count != 0:
atask = taskgetter.offset(random.randint(0, count-1)).first()
并产生如下错误:
ProgrammingError: (ProgrammingError) subquery in FROM must have an alias
LINE 3: FROM tasks, (SELECT ST_Union(tasks.geometry) AS "ST_Union_1"...
^
HINT: For example, FROM (SELECT ...) [AS] foo.
'SELECT count(*) AS count_1
FROM (SELECT tasks.id AS tasks_id
FROM tasks, (SELECT ST_Union(tasks.geometry) AS "ST_Union_1"
FROM tasks
WHERE tasks.state = %(state_1)s)
WHERE tasks.state = %(state_2)s AND ST_Disjoint(tasks.geometry, (SELECT ST_Union(tasks.geometry) AS "ST_Union_1"
FROM tasks
WHERE tasks.state = %(state_1)s))) AS anon_1' {'state_1': 1, 'state_2': 0}
答案 0 :(得分:1)
在黑暗中拍摄,因为我没有设置来测试它:
这似乎与SQLAlchemy的子查询相关,而不是GeoAlchemy,尝试在子查询的末尾添加.subquery()来生成别名(cf:http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#using-subqueries)
编辑: 仍然使用链接教程中的信息,我认为这可能有效:
state1 = session.query(
Task.geometry.ST_Union().label('taskunion')
).filter_by(state=1).subquery()
taskgetter = session.query(Task)\
.filter_by(state=0)
.filter(Task.geometry.ST_Disjoint(state1.c.taskunion))
在您在子查询上创建的列中添加标签,以便在超级查询中引用它。