我有一个模型的几何点列,所以我想定义setter来接收lat / lng而不是创建的WKTElement
。这是我的模型目前的样子:
class Poi(db.Model):
__tablename__ = 'api_pois'
id = db.Column(db.Integer, primary_key=True, unique=True)
name = db.Column(db.String(80), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('api_users.id'))
creation_time = db.Column(db.DateTime, default=func.now())
category_id = db.Column(db.Integer(), db.ForeignKey('api_poi_categories.id'))
category = db.relationship('PoiCategory')
geom = db.Column(Geometry('POINT', srid=4326), nullable=False)
metadata_poi = db.Column('metadata_poi')
def __init__(self, name, lat, lng, user_id=None, category_id=None, metadata_poi=None):
geom_str = 'POINT({} {})'.format(lng, lat)
self.name = name
self.user_id = user_id
self.category_id = category_id
self._geom = WKTElement(geom_str, srid=4326)
self.metadata_poi = metadata_poi
def __repr__(self):
return '<Poi %r %r>' % (self.id, self.name)
def as_dict(self, route_id=None):
sequence = None
if route_id:
from sintrafico.models.route import routes_pois
result = db.session.query(routes_pois).filter_by(route_id=route_id, poi_id=self.id). \
order_by(routes_pois.c._sequence).one_or_none()
if result:
sequence = result[2]
geom = db.session.query(Poi, func.ST_X(self.geom), func.ST_Y(self.geom)).filter(Poi.id == self.id).one_or_none()
return {
'id': self.id,
'name': self.name if not sequence else '%s - %s' % (sequence, self.name),
'lat': geom[2],
'lon': geom[1],
'city': str(City.city_for_coord(geom[2], geom[1])),
'sequence': sequence if sequence else None,
'category_id': self.category_id,
'category': self.category.name,
'metadata': self.metadata_poi
}
@property
def location(self):
geom = db.session.query(Poi, func.ST_X(self.geom), func.ST_Y(self.geom)).filter(Poi.id == self.id).one_or_none()
return {'lat': geom[2], 'lon': geom[1]}
@hybrid_property
def geom(self):
return self._geom
@geom.setter
def geom(self, (lat, lng)):
geom_str = 'POINT({} {})'.format(lng, lat)
self._geom = WKTElement(geom_str, srid=4326)
此代码在调用混合getter的geom = ...
内的as_dict()
行失败,因为Poi对象没有属性_geom
。现在,如果我将行更改为
geom = db.session.query(Poi, func.ST_X(self._geom), func.ST_Y(self._geom)).filter(Poi.id == self.id).one_or_none()
错误仍然存在,只是移动到该行而不是setter。如果我将声明更改为
_geom = db.Column(Geometry('POINT', srid=4326), nullable=False)
然后我得到的错误是格式错误的查询:
HINT: Perhaps you meant to reference the column "api_pois.geom".
[SQL: 'SELECT api_pois.id AS api_pois_id, api_pois.name AS api_pois_name, api_pois.user_id AS api_pois_user_id, api_pois.creation_time AS api_pois_creation_time, api_pois.category_id AS api_pois_category_id, ST_AsBinary(api_pois._geom) AS api_pois__geom, api_pois.metadata_poi AS api_pois_metadata_poi \nFROM api_pois \nWHERE api_pois.user_id = %(user_id_1)s ORDER BY api_pois.creation_time DESC'] [parameters: {'user_id_1': 1}]
在此代码的最后一行:
if args['q']:
pois = pois.filter(func.lower(Poi.name).like('%{}%'.format(args['q'].lower())))
if args['categories'] is not None and len(args['categories']) > 0:
pois = [x for x in pois if x.category_id in args['categories']]
我怎样才能让它发挥作用?
答案 0 :(得分:1)
明确命名您的geom列,而不是让声明性使用属性名称:
class Poi(db.Model):
...
_geom = db.Column('geom', Geometry('POINT', srid=4326), nullable=False)