【发布时间】:2018-10-29 02:57:26
【问题描述】:
我正在使用 Flask/SQLAlchemy 创建一个包含地图的 Web 应用程序,所以我自然使用的是 PostGIS 数据库。 geom 列需要 ST_Transform 并且我需要以某种方式将此列和所有其他列转换为 JSON。数据库的一般结构是:
from app import login, db
from datetime import datetime
from geoalchemy2 import Geometry
from time import time
from flask import current_app
from sqlalchemy import func
class Streets(db.Model):
id = db.Column(db.Integer, primary_key=True)
street = db.Column(db.String(50))
geom = db.Column(Geometry(geometry_type='LINESTRING'))
def to_dict(self):
data = {
'id': self.id,
'street': self.street,
'_geom': func.ST_AsGeoJSON(func.ST_Transform(self.geom, 4326))
}
return data
我的 api 路由把这个结果变成了一个 api:
return jsonify(Streets.query.get_or_404(id).to_dict())
但我不断收到此错误:NameError: name 'ST_AsGeoJSON' is not defined
我还尝试像这样创建我的_geom 值:
data['_geom'] = db.session.query(func.ST_AsGeoJSON(func.ST_Transform(self.geom, 4326)))
错误信息是:TypeError: Object of type 'BaseQuery' is not JSON serializable
最后,我尝试了这样的 api 路由:
data = Streets.to_dict(
db.session.query(
func.ST_AsGeoJSON(
func.ST_Transform(
Streets.geom, 4326
)
)
)
.filter(Streets.id==id))
return jsonify(data)
我得到一个不同的错误:
AttributeError: 'BaseQuery' object has no attribute 'id'
如果我在 flask shell 中运行它,它可以工作:
streets = db.session.query(
Streets.id,
Streets.street,
func.ST_AsGeoJSON(func.ST_Transform(Streets.geom, 4326)))
如何执行ST_Transform 并将 JSON 获取到我的 api 路由?
更新
我在 SQLALchemy 文档中发现了这一点,这让我取得了一些进展:“orm.column_property() 可用于映射 SQL 表达式”。所以我尝试将此添加到我的class Streets(db.Model):
coords = db.column_property(func.ST_AsGeoJSON(func.ST_Transform(geom, 4326)))
然后我像这样将它添加到data:
def to_dict(self):
data = {
'id': self.id,
'street': self.street,
'coords': self.coords
}
return data
但现在我对我的结果进行双重编码,一次输入 GeoJSON,然后我 jsonify 它:
return jsonify(Streets.query.get_or_404(id).to_dict())
所以我的api插入了\的:
{"coords": "{\"type\":\"MultiLineString\",\"coordinates\":[[[-80.8357132798193,35.2260689001034],[-80.8347602582754,35.2252424284259]]]}"}
而使用ST_AsText 只是将其转换为文本:
{"coords": "MULTILINESTRING((-80.8357132798193 35.2260689001034,-80.8347602582754 35.2252424284259))"}
我想我已经接近这个更新了,但是有没有人建议使用我的数据库其他字段的 JSON 来获取正确的 GeoJSON?
【问题讨论】:
标签: python json postgresql flask sqlalchemy