我正在使用Flask/SQLAlchemy创建一个包含地图的web应用程序,因此我自然使用PostGIS数据库。geom列需要一个ST_转换,我需要将此列和所有其他列转换为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
值,如下所示:
错误消息是: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_属性()可用于映射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?在
第一个错误
意味着您的示例代码不是您实际使用的代码。您忘了通过
func
访问它。在修复了这个问题之后,它也无法工作,因为您将混合SQL世界和Python世界。func.ST_AsGeoJSON(...)
创建一个SQL函数表达式对象,该对象应该编译为SQL并在查询中发送到DB,而不是传递给jsonify()
。在第二个错误
^{pr2}$应该有点明显。在
创建一个
Query
,以及一个过于宽泛的查询,因为您没有将其限制为获取当前对象的数据。Query
对象不可JSON序列化。在在
您将
Query
对象作为self
传递给Streets.to_dict()
,然后该对象尝试在中访问其id
属性它失败的原因很明显,即将一个不相关的对象作为实例传递给一个方法。在
column_property()
方法生成双编码的JSON,因为SQLAlchemy默认情况下不希望ST_AsGeoJSON
返回JSON,而是将其视为文本,而实际上它返回文本。尝试手动解码:相关问题 更多 >
编程相关推荐