<p>如果您使用的是<a href="http://postgis.refractions.net/" rel="nofollow">PostGIS</a>(几何体扩展版本<a href="http://www.postgresql.org/" rel="nofollow">postgres</a>),那么可以使用<a href="http://www.geoalchemy.org/index.html" rel="nofollow">GeoAlchemy</a>来利用这一点,它允许您根据PostGIS中可用的几何图元定义列类型。其中一种数据类型是<code>Point</code>,这正是它听起来的样子。在</p>
<p>PostGIS比普通的PostgreSQL更难设置,但是如果您真的打算根据实际的几何术语进行查询,那么额外的(大部分是一次性的)麻烦是值得的。在</p>
<p>使用纯SQLAlchemy的另一个解决方案是使用所需的语义<a href="http://www.sqlalchemy.org/docs/core/types.html#types-custom" rel="nofollow">define your own column types</a>,并在编译时将它们转换为数据库支持的更基本的类型。在</p>
<hr/>
<p>实际上,您可以使用属性,但不能与内置的<code>property</code>修饰符一起使用。您必须更加努力地创建自己的自定义描述符。在</p>
<p>你可能想要一个积分班。一个不错的选择就是
一个namedtuple,因为您不必担心代理分配
单个坐标的。属性分配全部或全部不分配</p>
<pre><code>Point = collections.namedtuple('Point', 'x y')
</code></pre>
<p>这至少可以让我们比较点值。下一步
编写描述符就是要完成它的方法。有两种方法可以考虑,<code>__get__</code>
和<code>__set__</code>,使用get时,有两种情况
一个实例,您应该处理实际的点值,以及
调用<em>类</em>,然后应该将其转换为列表达式。在</p>
<p>在最后一种情况下,返回什么有点棘手。我们想要的是
当与点比较时,它将返回一个列表达式,该表达式等于
具有单独坐标的各个列。我们再做一个
为那个上课。在</p>
^{pr2}$
<p>剩下的就是定义实际的描述符类。在</p>
<pre><code>class PointProperty(object):
def __init__(self, x, y):
''' x and y are the names of the coordinate attributes '''
self.x = x
self.y = y
def __set__(self, instance, value):
assert type(value) == Point
setattr(instance, self.x, value.x)
setattr(instance, self.y, value.y)
def __get__(self, instance, owner):
if instance is not None:
return Point(x=getattr(instance, self.x),
y=getattr(instance, self.y))
else: # called on the Class
return PointColumnProxy(getattr(owner, self.x),
getattr(owner, self.y))
</code></pre>
<p>可以这样使用:</p>
<pre><code>Base = sqlalchemy.ext.declarative.declarative_base()
class MyObject(Base):
x = Column(Float)
y = Column(Float)
pos = PointProperty('x', 'y')
</code></pre>