SQLAlchemy 学习(三)
来源:互联网 发布:银行卡换芯片卡通知 编辑:程序博客网 时间:2024/06/04 23:29
转载自:http://snoopyxdy.blog.163.com/blog/static/601174402014781473464/
本节将介绍使用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 = __engineproduct_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 = skuself.msrp = msrpself.summary = summaryself.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 = skuself.msrp = msrpself.summary = summaryself.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()
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来清理
0 0
- SQLAlchemy 学习(三)
- sqlalchemy学习(三):创建数据库表格
- sqlalchemy整理(三)
- Flask学习(三):SQLAlchemy无法创建数据库
- SQLAlchemy 学习(一)
- SQLAlchemy 学习(二)
- SQLAlchemy使用笔记--SQLAlchemy ORM(三)
- sqlAlchemy学习手册(一):sqlAlchemy的安装
- SqlAlchemy学习
- SQLAlchemy学习
- sqlalchemy文档资料翻译(三)
- SQLAlchemy (三)---使用操作连接符
- SQLAlchemy core 学习笔记(1) medata
- sqlalchemy 学习(二)scoped session
- 采用python中SQLalchemy模块访问数据库(三)
- sqlalchemy学习笔记
- sqlalchemy学习总结
- sqlalchemy 学习资料
- 追踪研读法破解EZ-USB的“远程唤醒”
- Python数据结构:映射(map)——字典
- 《转》PyQt4 动态添加treeWidget 的列表项
- 水仙花数(2013中南大学研究生上机复试题)
- Redis客户端Redisson中分布式锁RLock实现
- SQLAlchemy 学习(三)
- 自定义Toast
- linux tar 解压命令总结
- Sql Server 触发器实现多表之间同步增加、删除与更新
- vijos - P1077克隆龙 (找规律 + 指数型母函数 + python)
- wamp 下 Apache 局域网访问403的解决问题
- 容易出错的Java笔试题
- floyd-warshall算法
- cloudera manager安装和solrcloud搭建