SQLAlchemy 学习(三)
2015-08-21 11:44
190 查看
转载自:http://snoopyxdy.blog.163.com/blog/static/601174402014781473464/
本节将介绍使用orm进行数据的增删改查的例子
首先是对表和类的定义实例,
1、mapper中使用 exclude_properties
#排除id列名
mapper(Region, region_table, exclude_properties=['id'])
2、使用properties让数据对象属性和表属性进行关联
mapper(Region, region_table, properties=dict(
region_name=region_table.c.name,
region_id=region_table.c.id))
3、子查询映射关联(一般用不到)
4、延迟加载
比如数据库存储了BLOB类型的2进制文件,我们只是希望用到这个数据才去加载他,可以这样建立映射关系
5、mapper方法的一些参数
entity_name=None,
always_refresh=False,每次从数据库的查询到的数据都会重写内存数据,所以使用populate_existing()会优于这个参数。
allow_column_override=False,允许关联的属性和列名相同,这样列名就不会被映射了
allow_null_pks=False,允许主键为NULL,如果不设置,当主键为NULL时将不会跳过结构对象生成
batch=True,允许多个对象批处理save操作,如果设置为False,每个对象将会依次入库
column_prefix= None,自动加上映射列名属性的前缀
concrete=False,如果为true,说明使用的具体表继承
extension=None,一个映射的扩展对象或者映射扩展对象数组
inherits=None,另外一个映射对象,用来被继承的
inherit_condition=None,另外一个映射对象,继承的方式
inherit_foreign_keys=None,继承方式的参数
order_by=None,默认的排序方式对这个映射关系查询出的结果
non_primary=False,设定这个是不设置主键的映射
properties=None,一个字段,表示那些属性映射到表中,(不设置将会自动映射)
include_properties=None,一个属性数组,表示哪些属性会映射到表中,没有在数组中出现的属性不会映射到表中
exclude_properties=None,一个属性数组,那些属性确定不包括在数组中
primary_key=None,主键数组
polymorphic_on=None,
polymorphic_identity=None,
polymorphic_fetch='union',
select_table=None,
version_id_col=None
6、在映射中声明关系
一般关系对应有3种方式,1对多,多对多,1对1.
6.1、1对多的关系声明
6.2、多对多的关系声明
定义两张多对多的表和一张关系关联表
6.3、1对1的关系
1对1是特殊的1对多关系,只需要这样声明即可
7、backref避免重复两次声明关系
8、relation函数的参数
backref(relation( )only),反向的关系自动声明
cascade,层叠改变关系,主要用于1对多,当parent改变,Children也会改变,参数是all,delete,save-update,refresh-
expire,merge,expunge,delete-orphan
collection_class,
foreign_keys,外键申明数组
join_depth=None,连接深度
lazy=True,
order_by,排序
passive_deletes=False,如果为true,表示自动删除子关联,当主键为null或者父删除
post_update=False,如果设置为true,SQLAlchemy会分开CRUD操作,否则将会把CRUD操作放在一个声明里
primaryjoin,设定怎么连接父表和子表
remote_side,用于本表关联
secondary,在多对多关系中,用来声明关系表
secondaryjoin,多对多关系,声明父表如何链接关系表
uselist=True,1对1关系时声明
viewonly=False,只读操作连接
9、步入正轨,使用ORM进行查询和修改
两种方式生成session
第一种方式
第二种方式
sessionmaker接受参数:
bind=None,参数是一个数据库引擎或者连接字符串
binds=None,绑定其他mapper对象或者表
autoflush=True,自动flush
transactional=False,事物操作,当设置为true时,无需使用begin( )来声明事物开始,只需要执行commit()就可以提交事物,回滚使用rollback()
twophase=False,多数据库事物支持回滚
echo_uow=False,输出debug信息
extension=None,扩展字段
weak_identity_map=True,自动回收,如果设置为false,需要手动执行session的expunge( ), clear( ), or purge( )进行回收
10、将数据对象保存到session中
11、从session中删除
12、事物的操作
13、其他session方法
14、session查询的例子,只有当执行all等操作时,才回去数据库真正的执行操作
15、多表orm联查
16、from_statement,从select语句中获取查询条件
17、query对象的一些方法:
add_column( self, column, id=None ),对当前查询对象增加一列
add_entity( self, entity, alias=None, id=None ),对当前查询对象增加一个实体
all( self ),去数据库执行查询操作,然会resultProxy类型
autoflush( self, setting ),自动刷数据库
apply_avg( self, col ),增加SQL AVG,返回query对象
apply_max( self, col ),增加SQL MAX,返回query对象
apply_min( self, col ),增加SQL MIN,返回query对象
apply_sum( self, col ),增加SQL SUM,返回query对象
avg( self, col ),增加SQL avg,去数据库查询
count( self ),去数据库查询,并返回计数
distinct( self ),对整个query对象增加去重复,返回query
filter( self, criterion ),增加过滤对象,返回query
filter_by( self, **kwargs ),增加过滤字典,返回query
first( self ),去数据库返回查询结果的一条
from_statement( self, statement ),传入使用select()函数生成的查询语句,返回query
get( self, ident, reload=False, lockmode=None ),检查当前session是否具有此对象,如果有则
group_by( self, criterion ),分组,返回query
having( self, criterion ),增加having条件,返回query
join( self, prop, id=None, aliased=False, from_joinpoint=False ),新增加一个表,进行from查询,返回query
limit( self, limit ),limit限制,返回query
load( self, ident, raiseerr=True, lockmode=None ),从数据库返回这个实例
max( self, col ),执行SQL MAX
min( self, col, ),执行SQL MIN
offset( self, offset ),偏移量,返回query
one( self ),执行sql,返回结果,如果结果不是一个则抛出异常
options( self, *args ),根据数据中的mapper,返回一个新的query
order_by( self, criterion ),排序,返回query,
outerjoin( self, prop, id=None, aliased=False, from_joinpoint=False ),外联操作,返回query
params( self, *args, **kwargs ),更改现有的query中的查询绑定的值,返回query
populate_existing( self ),返回一个query,刷新所有对象
query_from_parent( cls, instance, property, **kwargs ) (classmethod),从另外一个query继承
reset_joinpoint( self ),重置连接属性,会影响filter_by,join,outerjoin
sum( self, col ),执行sum
with_lockmode( self, mode ),返回query,设置lockmodle
with_parent( self, instance, property=None ),从父query继承
__getitem__( self, item ) (indexing)
__iter__( self ) (iteration)
18、使用一个上下文线程session,tornado的例子
本节将介绍使用orm进行数据的增删改查的例子
首先是对表和类的定义实例,
# -*- coding: utf-8 -*-from sqlalchemy import *from sqlalchemy.orm import *from datetime import datetimeimport sysreload(sys)sys.setdefaultencoding('utf8') metadata = MetaData()__engine = create_engine('mysql://root:@192.168.150.3/test',convert_unicode=True, echo=True, encoding='UTF-8') metadata.bind = __engine product_table = Table( 'product', metadata, Column('sku', String(20), primary_key=True), Column('msrp', Numeric))class Product(object): def __init__(self, sku, msrp, summary=None): self.sku = sku self.msrp = msrp self.summary = summary self.categories = [] self.prices = [] def __repr__(self): return '<Product %s>' % self.skumapper(Product, product_table) Session = sessionmaker(bind=engine, echo_uow=True)session = Session() p1 = Product('123', 11.22)p2 = Product('456', 33.44)session.add(p1)session.add(p2)session.flush()
1、mapper中使用 exclude_properties
#排除id列名
mapper(Region, region_table, exclude_properties=['id'])
2、使用properties让数据对象属性和表属性进行关联
mapper(Region, region_table, properties=dict(
region_name=region_table.c.name,
region_id=region_table.c.id))
3、子查询映射关联(一般用不到)
average_price = select( [func.avg(product_price_table.c.price)], product_price_table.c.sku==product_table.c.sku)\ .as_scalar() \ .label('average_price')#打印语句print average_price(SELECT avg(product_price.price)FROM product_price, productWHERE product_price.sku = product.sku) AS average_price#执行子查询mapper(Product, product_table, properties=dict( average_price=column_property(average_price)))p = session.query(Product).get('123')print p.sku, p.msrp, p.average_price#打印结果123 12.34 12.34
4、延迟加载
比如数据库存储了BLOB类型的2进制文件,我们只是希望用到这个数据才去加载他,可以这样建立映射关系
product_table = Table('product', metadata,Column('sku', String(20), primary_key=True),Column('msrp', Numeric),Column('image1', Binary),Column('image2', Binary),Column('image3', Binary))mapper(Product, product_table, properties=dict(image1=deferred(product_table.c.image, group='images'),image2=deferred(product_table.c.image, group='images'),image3=deferred(product_table.c.image, group='images')))
5、mapper方法的一些参数
entity_name=None,
always_refresh=False,每次从数据库的查询到的数据都会重写内存数据,所以使用populate_existing()会优于这个参数。
allow_column_override=False,允许关联的属性和列名相同,这样列名就不会被映射了
allow_null_pks=False,允许主键为NULL,如果不设置,当主键为NULL时将不会跳过结构对象生成
batch=True,允许多个对象批处理save操作,如果设置为False,每个对象将会依次入库
column_prefix= None,自动加上映射列名属性的前缀
concrete=False,如果为true,说明使用的具体表继承
extension=None,一个映射的扩展对象或者映射扩展对象数组
inherits=None,另外一个映射对象,用来被继承的
inherit_condition=None,另外一个映射对象,继承的方式
inherit_foreign_keys=None,继承方式的参数
order_by=None,默认的排序方式对这个映射关系查询出的结果
non_primary=False,设定这个是不设置主键的映射
properties=None,一个字段,表示那些属性映射到表中,(不设置将会自动映射)
include_properties=None,一个属性数组,表示哪些属性会映射到表中,没有在数组中出现的属性不会映射到表中
exclude_properties=None,一个属性数组,那些属性确定不包括在数组中
primary_key=None,主键数组
polymorphic_on=None,
polymorphic_identity=None,
polymorphic_fetch='union',
select_table=None,
version_id_col=None
6、在映射中声明关系
一般关系对应有3种方式,1对多,多对多,1对1.
6.1、1对多的关系声明
mapper(Store, store_table)mapper(Region, region_table, properties=dict( stores=relation(Store)))mapper(Region, region_table, properties=dict(#当两张表有多个外键关系时,SQLAlchemy无法判断用哪个作为外键,可以指定它stores=relation(Store,primaryjoin=(store_table.c.region_id==region_table.c.id))))
6.2、多对多的关系声明
定义两张多对多的表和一张关系关联表
category_table = Table('category', metadata,Column('id', Integer, primary_key=True),Column('level_id', None, ForeignKey('level.id')),Column('parent_id', None, ForeignKey('category.id')),Column('name', String(20))) product_table = Table('product', metadata,Column('sku', String(20), primary_key=True),Column('msrp', Numeric)) product_category_table = Table('product_category', metadata,Column('product_id', None, ForeignKey('product.sku'), primary_key=True),Column('category_id', None, ForeignKey('category.id'), primary_key=True)) #定义mapper关系mapper(Category, category_table, properties=dict( products=relation(Product, secondary=product_category_table))) #另外一个关系映射也要声明一下 mapper(Product, product_table, properties=dict( categories=relation(Category, secondary=product_category_table)))
6.3、1对1的关系
1对1是特殊的1对多关系,只需要这样声明即可
mapper(Product, product_table, properties=dict( summary=relation(ProductSummary, uselist=False)))
7、backref避免重复两次声明关系
mapper(Level, level_table, properties=dict( categories=relation(Category, backref='level'))) mapper(Category, category_table, properties=dict( products=relation(Product, secondary=product_category_table, backref='categories'))) #同样可以使用backref()方法来建立另外一个1对1的关系 mapper(ProductSummary, product_summary_table, properties=dict( product=relation(Product, backref=backref('summary', uselist=False)))) mapper(Product, product_table)
8、relation函数的参数
backref(relation( )only),反向的关系自动声明
cascade,层叠改变关系,主要用于1对多,当parent改变,Children也会改变,参数是all,delete,save-update,refresh-
expire,merge,expunge,delete-orphan
collection_class,
foreign_keys,外键申明数组
join_depth=None,连接深度
lazy=True,
order_by,排序
passive_deletes=False,如果为true,表示自动删除子关联,当主键为null或者父删除
post_update=False,如果设置为true,SQLAlchemy会分开CRUD操作,否则将会把CRUD操作放在一个声明里
primaryjoin,设定怎么连接父表和子表
remote_side,用于本表关联
secondary,在多对多关系中,用来声明关系表
secondaryjoin,多对多关系,声明父表如何链接关系表
uselist=True,1对1关系时声明
viewonly=False,只读操作连接
9、步入正轨,使用ORM进行查询和修改
两种方式生成session
第一种方式
Session = sessionmaker(bind=engine)
第二种方式
Session = sessionmaker()Session.configure(bind=engine)
sessionmaker接受参数:
bind=None,参数是一个数据库引擎或者连接字符串
binds=None,绑定其他mapper对象或者表
autoflush=True,自动flush
transactional=False,事物操作,当设置为true时,无需使用begin( )来声明事物开始,只需要执行commit()就可以提交事物,回滚使用rollback()
twophase=False,多数据库事物支持回滚
echo_uow=False,输出debug信息
extension=None,扩展字段
weak_identity_map=True,自动回收,如果设置为false,需要手动执行session的expunge( ), clear( ), or purge( )进行回收
10、将数据对象保存到session中
product_table = Table( 'product', metadata, Column('sku', String(20), primary_key=True), Column('msrp', Numeric)) class Product(object): def __init__(self, sku, msrp, summary=None): self.sku = sku self.msrp = msrp self.summary = summary self.categories = [] self.prices = [] def __repr__(self): return '<Product %s>' % self.sku mapper(Product, product_table) Session = sessionmaker(bind=engine, echo_uow=True)session = Session()p1 = Product('123', 11.22)p2 = Product('456', 33.44)session.add(p1)session.add(p2)session.flush()
11、从session中删除
session.delete(p1)
12、事物的操作
session.begin()session.commit()session.rollback()
13、其他session方法
save( self, obj, entity=None),delete( self, obj ),从下次flush中,删除对象expire( self, obj ),refresh( self, obj )merge( self, obj, entity=None )expunge( self, obj ),在session中删除整个对这个对象的引用update( self, obj, entity=None ),get( self, class_, ident, **kwargs ),load( self, class_, ident, **kwargs )query( self, mapper_or_class, *addtl_entities, **kwargs ),查询clsoe(),摧毁这个sessionexecute( self, clause, params=None, mapper=None, **kwargs ),identity_mapnewdirtydeleted
14、session查询的例子,只有当执行all等操作时,才回去数据库真正的执行操作
query = session.query(Product)query = query.filter_by(msrp=11.22)query = query.limit(3)print query.all() #.first()
15、多表orm联查
query = session.query(Product)query = query.join('categories')query = query.filter_by(name='T-Shirts')print query.all()[<Product 222>]print querySELECT product.sku AS product_sku, product.msrp AS product_msrpFROM product JOIN product_category ON product.sku = product_category.product_id JOIN category ON category.id = product_category.category_idWHERE category.name = ? ORDER BY product.oidjoin方法是inner join,outjoin则是outerjoin#filter方法实例 query = query.filter(or_(Category.c.name=='Pants', Category.c.name==None))
16、from_statement,从select语句中获取查询条件
session.clear() stmt = select([product_table.c.sku]) query = session.query(Product).from_statement(stmt) for prod in query: print prod, prod.msrp
17、query对象的一些方法:
add_column( self, column, id=None ),对当前查询对象增加一列
add_entity( self, entity, alias=None, id=None ),对当前查询对象增加一个实体
all( self ),去数据库执行查询操作,然会resultProxy类型
autoflush( self, setting ),自动刷数据库
apply_avg( self, col ),增加SQL AVG,返回query对象
apply_max( self, col ),增加SQL MAX,返回query对象
apply_min( self, col ),增加SQL MIN,返回query对象
apply_sum( self, col ),增加SQL SUM,返回query对象
avg( self, col ),增加SQL avg,去数据库查询
count( self ),去数据库查询,并返回计数
distinct( self ),对整个query对象增加去重复,返回query
filter( self, criterion ),增加过滤对象,返回query
filter_by( self, **kwargs ),增加过滤字典,返回query
first( self ),去数据库返回查询结果的一条
from_statement( self, statement ),传入使用select()函数生成的查询语句,返回query
get( self, ident, reload=False, lockmode=None ),检查当前session是否具有此对象,如果有则
group_by( self, criterion ),分组,返回query
having( self, criterion ),增加having条件,返回query
join( self, prop, id=None, aliased=False, from_joinpoint=False ),新增加一个表,进行from查询,返回query
limit( self, limit ),limit限制,返回query
load( self, ident, raiseerr=True, lockmode=None ),从数据库返回这个实例
max( self, col ),执行SQL MAX
min( self, col, ),执行SQL MIN
offset( self, offset ),偏移量,返回query
one( self ),执行sql,返回结果,如果结果不是一个则抛出异常
options( self, *args ),根据数据中的mapper,返回一个新的query
order_by( self, criterion ),排序,返回query,
outerjoin( self, prop, id=None, aliased=False, from_joinpoint=False ),外联操作,返回query
params( self, *args, **kwargs ),更改现有的query中的查询绑定的值,返回query
populate_existing( self ),返回一个query,刷新所有对象
query_from_parent( cls, instance, property, **kwargs ) (classmethod),从另外一个query继承
reset_joinpoint( self ),重置连接属性,会影响filter_by,join,outerjoin
sum( self, col ),执行sum
with_lockmode( self, mode ),返回query,设置lockmodle
with_parent( self, instance, property=None ),从父query继承
__getitem__( self, item ) (indexing)
__iter__( self ) (iteration)
18、使用一个上下文线程session,tornado的例子
Session = scoped_session(sessionmaker( bind=engine, autoflush=True, transactional=True))session = Session()session2 = Session()session is session2#用完需要调用close来清理
相关文章推荐
- 软件工程文档中的数据库模型设计
- mongodb停止数据库
- mysql如何处理大量数据
- "ORA-00942: 表或视图不存在 "的原因和解决方法
- Ubuntu 安装mysql和简单操作
- 在Oracle中更新数据时,抛出:ORA-01008: not all variables bound
- MySQL中视图
- sqlserver——insert into /select into/create table/drop
- JAVA读取Oracle数据库BLOB字段数据文件并保存到本地文件
- 【sql】mysql left join,right join,inner join超详细用法解析
- Importing/Indexing database (MySQL or SQL Server) in Solr using Data Import Handler--转载
- mysql内置函数
- redis:hash数据类型与操作
- Oracle数据库的启动和关闭
- PostgreSQL表空间、数据库、模式、表、用户/角色之间的关系(转)
- Spring-Data-Redis特性
- PostgreSQL学习手册-模式Schema(转)
- SQL-Oracle异常--java.sql.SQLDataException: ORA-01861: 文字与格式字符串不匹配
- 修改SQL Server 2005 数据库文件名字
- SQL学习