uliorm 添加 PICKLE 字段和对 manytomany through 的改进

1. Pickle类型其实在SQLAlchemy中已经存在,不过在uliorm中没有直接对应的字段。现在已经加进去了,可以通过:

Field(PICKLE)

来定义,和定义BLOB类似。

使用PICKLE类型,你可以保存一个python的对象到这个字段中,如list,
dict等,这样在保存到数据库中时会自动使用pickle来进行序列化处理。从数据库中取出来时,也会自动反序列化。这样存一些复杂的数据时会非常方便。注意,建议只保存基本数据类型,如果存在导入其它的模块的情况,应该先把相关的模块和类都导入后再处理。(不过这个我没有试,因为目前还没有这个需要。)

2. ManyToMany 目前可以使用through来定义第三张表。如果不使用through,则会自动创建表。使用through的好处就是除了定义A,B两个表的id字段外,还可以定义其它的字段,比简单的创建第三张表更灵活。例如:

   >>> class User(Model):
   ...     username = Field(CHAR, max_length=20)
   ...     year = Field(int)
   >>> class Group(Model):
   ...     name = Field(str, max_length=20)
   ...     users = ManyToMany(User, through='relation')
   >>> class Relation(Model):
   ...     user = Reference(User)
   ...     group = Reference(Group)
   ...     year = Field(int)

这样定义了Relation为第三张表。添加关系时如:

   >>> a = User(username='limodou', year=5)
   >>> a.save()
   >>> g1 = Group(name='python')
   >>> g1.save()
   >>> r1 = Relation(user=a, group=g1, year=10)
   >>> r1.save()

关系加进去了。同时在定义关系时,还给关系的year字段赋了一个值。

现在有一个需求,我想通过g1.users.all()来得到对应的用户,同时我还想得到每个用户关系中的year字段怎么办?

一种方法是通过Relation()来查询,如:

for r in Relation.filter(Relation.c.group==g1.id):
   #通过r.user可以得到user对象
   #通过r.year可以得到year属性

但是上面我们得到的是Relation的对象,不是直接得到user对象。

第二种方法就是采用新优化的功能,执行如下:

for u in g1.users.all().with_relation():
   #u就是user对象
   #u.relation.year就是对应关系的year属性

使用一个with_relation()方法就可以解决这个问题。它的作用是:一旦执行,将会在取出ManyToMany对象的同时,将关系对象也同时存在ManyToMany对象中,好象是ManyToMany对象的属性。这样的话比较方便。其中:with_relation()可以有一个参数,就是关系对象的属性名。如果不给,则缺省为'relation'。因此上面的代码就是缺省情况的使用。

这种方法有一个限制,那就是你的第三张表需要使用through方法来传入,也就是第三张表是你自已定义的,而不是自动生成的。因为自动生成的只是一个Table对象,而不是一个Model。并且,自动生成的表只有两个字段。

有兴趣的可以试用一下。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。