用sqlalchemy在sqlite数据库中存储列表/元组

2024-05-15 02:50:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类,它保存我在屏幕上绘制的东西的大小和位置。我使用sqlalchemy和sqlite数据库来持久化这些对象。但是,位置是一个2D值(x和y),我想有一个方便的方法来访问它

MyObject.pos # preferred, simpler interface

# instead of: 
MyObject.x 
MyObject.y # inconvenient

我可以使用属性,但是这个解决方案不是最佳的,因为我不能基于属性进行查询

^{pr2}$

有没有什么方法可以使用集合或关联代理来获得我想要的行为?在


Tags: of对象方法pos数据库sqlite属性屏幕
2条回答

如果您使用的是PostGIS(几何体扩展版本postgres),那么可以使用GeoAlchemy来利用这一点,它允许您根据PostGIS中可用的几何图元定义列类型。其中一种数据类型是Point,这正是它听起来的样子。在

PostGIS比普通的PostgreSQL更难设置,但是如果您真的打算根据实际的几何术语进行查询,那么额外的(大部分是一次性的)麻烦是值得的。在

使用纯SQLAlchemy的另一个解决方案是使用所需的语义define your own column types,并在编译时将它们转换为数据库支持的更基本的类型。在


实际上,您可以使用属性,但不能与内置的property修饰符一起使用。您必须更加努力地创建自己的自定义描述符。在

你可能想要一个积分班。一个不错的选择就是 一个namedtuple,因为您不必担心代理分配 单个坐标的。属性分配全部或全部不分配

Point = collections.namedtuple('Point', 'x y')

这至少可以让我们比较点值。下一步 编写描述符就是要完成它的方法。有两种方法可以考虑,__get____set__,使用get时,有两种情况 一个实例,您应该处理实际的点值,以及 调用,然后应该将其转换为列表达式。在

在最后一种情况下,返回什么有点棘手。我们想要的是 当与点比较时,它将返回一个列表达式,该表达式等于 具有单独坐标的各个列。我们再做一个 为那个上课。在

^{pr2}$

剩下的就是定义实际的描述符类。在

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))

可以这样使用:

Base = sqlalchemy.ext.declarative.declarative_base()
class MyObject(Base):
    x = Column(Float)
    y = Column(Float)

    pos = PointProperty('x', 'y')

用PickleType列类型定义表。然后它将自动持久化Python对象,只要它们是可pickle的。元组是可以腌制的。在

mytable = Table("mytable", metadata,
       Column('pos', PickleType(),
        ...
)

相关问题 更多 >

    热门问题