使用 sqlalchemy 在 sqlite 数据库中存储列表/元组
我有一个类保存我在屏幕上绘制的内容的大小和位置。我使用 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()
是否有某种方法使用集合或关联代理来获得我想要的行为?
I have a class that holds the size and position of something I draw to the screen. I am using sqlalchemy with a sqlite database to persist these objects. However, the position is a 2D value (x and y) and I'd like to have a convienent way to access this as
MyObject.pos # preferred, simpler interface
# instead of:
MyObject.x
MyObject.y # inconvenient
I can use properties but this solution isn't optimal since I cannot query based on the properties
session.query(MyObject).filter(MyObject.pos==some_pos).all()
Is there some way to use collections or association proxies to get the behavior I want?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用 PostGIS (postgres),您可以使用 GeoAlchemy,它允许您根据 PostGIS 中可用的几何基元定义列类型。其中一种数据类型是
Point
,顾名思义。PostGIS 比普通 PostgreSQL 更难设置,但如果您确实打算根据实际几何术语进行查询,那么额外的(大部分是一次性的)麻烦是值得的。
使用普通 SQLAlchemy 的另一个解决方案是定义您自己的列类型具有所需的语义,并在编译时将它们转换为数据库支持的更原始类型。
实际上,您可以使用属性,但不能使用内置
property
装饰器。您必须更加努力地工作并创建您自己的自定义描述符。您可能想要一个积分课程。一个不错的选择实际上是使用
一个命名元组,因为您不必担心代理分配
的个体坐标。该属性要么全部分配,要么全部不分配,
这至少可以让我们比较点值。下一步在
编写描述符就是通过它的方法来工作。有两种方法可以考虑,
__get__
和
__set__
,以及get,两种情况,当调用时一个实例,您应该处理实际的点值,并且何时
调用类,您应该将其转换为列表达式。
在最后一种情况下返回什么有点棘手。我们想要的是某样东西
与点比较时,将返回一个列表达式,该表达式等于
具有单独坐标的各个列。我们再做一个
为此类。
剩下的就是定义实际的描述符类。
可以这样使用:
If you are using PostGIS (Geometry extended version of postgres), you can take advantage of that using GeoAlchemy, which allows you to define Column types in terms of geometric primitives available in PostGIS. One such data type is
Point
, which is just what it sounds like.PostGIS is a bit more difficult to set up than vanilla PostgreSQL, but if you actually intend to do queries based on actual geometric terms, it's well worth the extra (mostly one time) trouble.
Another solution, using plain SQLAlchemy is to define your own column types with the desired semantics, and translate them at compile time to more primitive types supported by your database.
Actually, you could use a property, but not with the builtin
property
decorator. You'd have to have to work a little harder and create your own, custom descriptor.You probably want a point class. A decent option is actually to use
a namedtuple, since you don't have to worry about proxying assignment
of individual coordinates. The property gets assigned all or nothing
This would let us at least compare point values. The next step in
writing the descriptor is to work through its methods. There are two methods to think about,
__get__
and
__set__
, and with get, two situations, when called onan instance, and you should handle actual point values, and when
called on the class, and you should turn it into a column expression.
What to return in that last case is a bit tricky. What we want is something
that will, when compared to a point, returns a column expression that equates
the individual columns with the individual coordinates. well make one more
class for that.
All that's left is to define the actual descriptor class.
which could be used thusly:
使用 PickleType 列类型定义表。然后它会自动保留 Python 对象,只要它们是可pickle的。元组是可腌制的。
Define your table with a PickleType column type. It will then automatically persist Python objects, as long as they are pickleable. A tuple is pickleable.