我有一个名为 postgis 的数据库表,它使用 geoalchemy2/sqlalchemytasks
映射到一个 python 类- 每个条目都有一个 MultiPolygon和一个整数。总的来说,我的数据库中的条目涵盖了一个地理区域。我想选择一个 state=0 的随机条目,它在地理上与 state=1 的任何条目都不相邻。Task
geometry
state
这是选择 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可以检测它们是否相交。所以看来我应该能够选择 state=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}