显示标签为“SQLAlchemy”的博文。显示所有博文
显示标签为“SQLAlchemy”的博文。显示所有博文

九月 18, 2006

ActiveMapper in SQLAlchemy

ActiveMapper 是SA里面很酷的extension
简化了SA先定义表再mapping的繁琐,又能充分利用SA mapper 的特性

下面是ActiveMapper最基础的用法。


from sqlalchemy.ext.activemapper import ActiveMapper, column, \
objectstore, metadata, one_to_many, one_to_one, many_to_many

metadata.connect('sqlite:///../idtest.db')
metadata.engine.echo = True

user_group = Table("user_group", metadata,
Column("user_id", Integer,
ForeignKey("tg_user.user_id"),
primary_key=True),
Column("group_id", Integer,
ForeignKey("tg_group.group_id"),
primary_key=True))

class Group(ActiveMapper):
class mapping:
__table__="tg_group"
group_id = column(Integer, primary_key=True)
group_name = column(Unicode(16), unique=True)
created = column(DateTime, default=datetime.now)

class User(ActiveMapper):
class mapping:
__table__="tg_user"
user_id = column(Integer, primary_key=True)
user_name = column(Unicode(16), unique=True)
password = column(Unicode(40))
created = column(DateTime, default=datetime.now)
groups = many_to_many("Group", user_group, backref="users")

u = User()
u.user_name = 'test'
g = Group()
g.group_name = 'admin'
g.users.append(u)
objectstore.flush()


在mapper的使用上基本上与SA一般的用法没什么差别.
要注意的就是在申明class的时候,使用one_to_many, many_to_many这些函数来定义各个表之间的关系。
而与数据库的连接,则用sqlalchemy下面的 metadata, objectstore来进行
metadata.connect()连接数据库
objectstore.flush()将对对象的修改提交到数据库

ps:
现在activemapper有一个小bug就是,如果两个表是多对多的关系,
那么不能在两个class下面同时申明many_to_many,
而只要给many_to_many一个backref参数,这个属性就会自动添加到对应的class下

八月 03, 2006

ActiveMapper make Turbogears easy to use SqlAlchemy.

前几天第一次用了SA,感觉还是不错的


但是按他文档里面的方法,要先定义table,再定义一个类用于和这个table的邦定,最后还需要调用mapper()绑定,还是挺繁琐的


特别是当我用在tg中,加上在model.py中的定义和controller的调试就更烦了,不过利用sa最新的插件ActiveMapper,可以把这些繁琐的步骤通通抛掉


不过am相关的文档较少,用一个最简单的例子说明下使用吧



from sqlalchemy import *
from sqlalchemy.ext.activemapper import ActiveMapper, column
class User(ActiveMapper):
class mapping:
__table__ = "user_table"
id = column(Integer, primary_key=True)
name = column(String)

首先定义一个以ActiveMapper为基类的class,再通过mapping类使得这个class能绑定到正确的表上


__table__定义的表名,表中的字段用column声明(具体的参数和SA的Column一样,SA的文档写得很清楚了)


把User定义放入model.py中,在controller中import就可以使用了(基本上和SqlObject定义的class用法一样)



from fv.model import User as usr
class index(controllers.Controller):
@expose(template="json")
def index(self):
res = usr.select()
return dict(res = res[0].name)

如果还想对结果排序还可以使用



res = usr.select(order_by=[asc(usr.c.name)])

注意要先从sqlalchemy中import asc,更多的查询方式可以参照SA上面的 Where Clause


现在ActiveMapper相关的文档还比较少,不过随着tg版本的推进和SA API的稳定,很快就会有更多相关的文档了


另外也希望AM这么灵活的ORM机制能在SA中发挥更大的作用




Technorati : , ,
Del.icio.us : , ,

八月 02, 2006

WHERE clause in SqlAlchemy

在以前使用SQLObject的时候,就对复合查询特别头痛,在邮件列表里面才了解到要怎样才能得到排序、限制查询个数这样的操作。


SqlAlchemy也有这样的问题,只是SA的文档比SO要想尽很多,这里就介绍了WHERE语句在SA中的实现。


逻辑关系: or_() , and_() , not_() , in_()



c = users.select(or_(users.c.user_name=='jack',
users.c.user_name=='ed')).execute()


c = users.select(and_(users.c.user_name=='jack',
users.c.password=='dog')).execute()


c = users.select(not_(
or_(users.c.user_name=='jack',
users.c.password=='dog')
)).execute()


c = users.select(users.c.user_name.in_(
'jack', 'ed', 'fred')).execute()

排序: order_by



c = users.select(order_by=
[asc(users.c.user_name)]).execute()

其中asc()与desc()可以指明排序的方式(升序/降序)


限制查询的项数: limit, offset, distintic



c = users.select(limit=10,
offset=20, distintic=True).execute()





Technorati :
Del.icio.us :