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

标签 python sqlite sqlalchemy

我有一个类,用于保存我在屏幕上绘制的内容的大小和位置。我使用 sqlalchemy 和 sqlite 数据库来保存这些对象。但是,该位置是一个 2D 值(x 和 y),我希望有一种方便的方法来访问它

MyObject.pos # preferred, simpler interface

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

我可以使用属性,但此解决方案不是最佳的,因为我无法根据属性进行查询

session.query(MyObject).filter(MyObject.pos==some_pos).all()

是否有某种方法可以使用集合或关联代理来获得我想要的行为?

最佳答案

如果您使用PostGIS ( postgres 的几何扩展版本),您可以使用 GeoAlchemy 来利用它,它允许您根据 PostGIS 中可用的几何基元定义列类型。其中一种数据类型是Point,顾名思义。

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

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


实际上,您可以使用属性,但不能使用内置 property 装饰器。您必须更加努力地工作并创建您自己的自定义描述符。

您可能想要一个积分类(class)。一个不错的选择实际上是使用 一个命名元组,因为您不必担心代理分配 的个体坐标。该属性要么全部分配,要么全部不分配

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

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

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

class PointColumnProxy(object):
    def __init__(self, x, y):
        ''' these x and y's are the actual sqlalchemy columns '''
        self.x, self.y = x, y

    def __eq__(self, pos):
        return sqlalchemy.and_(self.x == pos.x,
                               self.y == pos.y)

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

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

关于python - 使用 sqlalchemy 在 sqlite 数据库中存储列表/元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6092616/

相关文章:

python - 如何迭代 pandas 列中的列表以查找匹配项?

python - 'if not in' 时间复杂度

python - GAE Python 中的 CSS 编译器

objective-c - 以编程方式编辑 SQLite 数据库中的数据

python - 使用 SQLAlchemy OrderingList 更新现有对象的顺序

python - 哪种 DBDriver 适用于 Python3x 和 SQLAlchemy0.8 for MySQL?

python - Django 信号与 channel

sqlite - 如何清理sqlite数据库?

java - android游标如何从列中获取空值

python - 当数据库查询没有获取结果时,我怎么会出错?