python sqlalchemy_python之sqlalchemy

877318-20160703111820843-801698782.png

ORM:

ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。 正确使用ORM的前提是了解关系数据库的原理。 ORM就是把数据库表的行与相应的对象建立关联,互相转换。 由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应地, ORM框架也可以提供两个对象之间的一对多、多对多等功能。

一 单表操作(不涉及一对多,多对多)

ContractedBlock.gif

ExpandedBlockStart.gif

#coding:utf8

import sqlalchemyfromsqlalchemy import create_enginefromsqlalchemy.ext.declarative import declarative_basefromsqlalchemy import Column, Integer, Stringfromsqlalchemy.orm import sessionmaker

print(sqlalchemy.__version__)

engine= create_engine('sqlite:///dbyuan1.db', echo=True)

Base=declarative_base()#生成一个SQLORM基类classUser(Base):

__tablename__= 'users'id= Column(Integer, primary_key=True)

name=Column(String)

fullname=Column(String)

password=Column(String)

def __repr__(self):return "" %(

self.name, self.fullname, self.password)

Base.metadata.create_all(engine) #创建所有表结构

ed_user= User(name='xiaoyu', fullname='Xiaoyu Liu', password='123')

print(ed_user)

#这两行触发sessionmaker类下的__call__方法,return得到 Session实例,赋给变量session,所以session可以调用Session类下的add,add_all等方法

MySession= sessionmaker(bind=engine)

session=MySession()

session.add(ed_user)

# our_user= session.query(User).filter_by(name='ed').first()

# SELECT* FROM users WHERE name="ed" LIMIT 1;

# session.add_all([

# User(name='alex', fullname='Alex Li', password='456'),

# User(name='alex', fullname='Alex old', password='789'),

# User(name='peiqi', fullname='Peiqi Wu', password='sxsxsx')])

session.commit()

#print(">>>",session.query(User).filter_by(name='ed').first())

#print(session.query(User).all())

#for row insession.query(User).order_by(User.id):

# print(row)

#for row in session.query(User).filter(User.name.in_(['alex', 'wendy', 'jack'])):#这里的名字是完全匹配

# print(row)

#for row in session.query(User).filter(~User.name.in_(['ed', 'wendy', 'jack'])):

# print(row)

#print(session.query(User).filter(User.name== 'ed').count())

#fromsqlalchemy import and_, or_

#for row in session.query(User).filter(and_(User.name == 'ed', User.fullname == 'Ed Jones')):

# print(row)

#for row in session.query(User).filter(or_(User.name == 'ed', User.name == 'wendy')):

# print(row)

View Code

877318-20160705142107655-1149996752.png

二 一对多的关联表操作

实例1:

ContractedBlock.gif

ExpandedBlockStart.gif

#coding:utf8

import sqlalchemyfromsqlalchemy import create_enginefromsqlalchemy.ext.declarative import declarative_basefromsqlalchemy import Column, Integer, String,ForeignKeyfromsqlalchemy.orm import sessionmaker,relationship

engine= create_engine('sqlite:///dbyuan2.db', echo=True)

Base=declarative_base()classFather(Base):

__tablename__= 'father'#id= Column(Integer, primary_key=True)里的数据类型一定写整型(Integer)

id= Column(Integer, primary_key=True)

name= Column(String(20))

def __repr__(self):return "" %self.nameclassSon(Base):

__tablename__= 'son'id= Column(Integer, primary_key=True)

name= Column(String(20))

#ForeignKey建在多的一方

father_id= Column(String(20), ForeignKey('father.id'))

father=relationship("Father",backref="son", order_by=id)

def __repr__(self):return "" %self.name

Base.metadata.create_all(engine)

Session= sessionmaker(bind=engine)

session=Session()

f1= Father(name='zhangsan')

f2= Father(name='lisi')

f3= Father(name='wangwu')

f1.son= [Son(name='zhangdasan'),Son(name='zhangersan')]

session.add(f1)

session.commit()for u, a insession.query(Father, Son).\

filter(Father.id==Son.id).\

all():

print u, a #

View Code

877318-20160705142623530-957596745.png

877318-20160705142641921-1514286290.png

实例2:

ContractedBlock.gif

ExpandedBlockStart.gif

#__ *__ coding:utf8__*__fromsqlalchemy import create_enginefromsqlalchemy.ext.declarative import declarative_basefromsqlalchemy import Column, Integer, String,and_,or_,ForeignKeyfromsqlalchemy.orm import sessionmaker,relationship

Base=declarative_base() #生成一个SqlORM 基类

engine= create_engine('sqlite:///dbyuan3.db', echo=True)classHost(Base):

__tablename__='host'id= Column(Integer,primary_key=True,autoincrement=True)

hostname= Column(String(64),unique=True,nullable=False)

ip_addr= Column(String(128),unique=True,nullable=False)

port= Column(Integer,default=22)

#前提 一个主机只能属于一个组

group_id=Column(Integer,ForeignKey('group.id'))

group=relationship('Group',backref='host')

def __repr__(self):return "id:%s hostname:%s port:%s"%(self.id,self.hostname,self.port)classGroup(Base):

__tablename__='group'id=Column(Integer,primary_key=True)

name=Column(String(64),unique=True,nullable=False)

def __repr__(self):return "id:%s hostname:%s"%(self.id,self.name)

Base.metadata.create_all(engine) #创建所有表结构if __name__ == '__main__':

SessionCls= sessionmaker(bind=engine,autoflush=False)

session=SessionCls()

g1=Group(name='g1')

g2=Group(name='g2')

g3=Group(name='g3')

session.add_all([g1,g2,g3])

session.commit()

h1= Host(hostname='localhost',ip_addr='127.0.0.1',group_id=g1.id)#g1如果在这之前没有提交,group_id拿到的永远是一个空值

h2= Host(hostname='ubuntu',ip_addr='192.168.2.243',port=20000)

session.add_all([h1,h2])

session.commit()

g1=session.query(Group).filter(Group.name=='g1').first()

h=session.query(Host).filter(Host.hostname=='localhost').first()#注意要加上first(),否则报错,注意与all()结果的不同

print"<<<",g2

print">>>",h

print(h.group.name)

print g1.host

print g1.host[0].hostname

#g2.host什么结果?(未绑定,无结果)

View Code

877318-20160705151831608-2036381659.png

877318-20160705151855733-1580752022.png

三 多对多的关联表操作

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python

#-*- coding:utf-8 -*-

fromsqlalchemy import create_engine,and_,or_,func,Tablefromsqlalchemy.ext.declarative import declarative_basefromsqlalchemy import Column, Integer, String,ForeignKeyfromsqlalchemy.orm import sessionmaker,relationship

Base=declarative_base() #生成一个SqlORM 基类

Host2Group= Table('host_2_group',Base.metadata,

Column('host_id',ForeignKey('host.id'),primary_key=True),

Column('group_id',ForeignKey('group.id'),primary_key=True),)

engine= create_engine('sqlite:///dbyuan4.db', echo=True)classHost(Base):

__tablename__= 'host'id= Column(Integer,primary_key=True,autoincrement=True)

hostname= Column(String(64),unique=True,nullable=False)

ip_addr= Column(String(128),unique=True,nullable=False)

port= Column(Integer,default=22)

group= relationship('Group',

secondary=Host2Group,

backref='host_list')

#group=relationship("Group",back_populates='host_list')

def __repr__(self):return "" %(self.id,

self.hostname,

self.ip_addr)classGroup(Base):

__tablename__= 'group'id= Column(Integer,primary_key=True)

name= Column(String(64),unique=True,nullable=False)

def __repr__(self):return "" %(self.id,self.name)

Base.metadata.create_all(engine) #创建所有表结构if __name__ == '__main__':

SessionCls= sessionmaker(bind=engine,autoflush=False)

session=SessionCls()

g1= Group(name='g1')

g2= Group(name='g2')

g3= Group(name='g3')

g4= Group(name='g4')

session.add_all([g1,g2,g3,g4])

session.commit()

#g4= session.query(Group).filter(Group.name=='g4').first()

#h= session.query(Host).filter(Host.hostname=='localhost').update({'group_id':g4.id})

#h= session.query(Host).filter(Host.hostname=='localhost').first()

#print("h1:",h.group.name )

#print("g:",g4.host_list )

h1= Host(hostname='h1',ip_addr='192.168.1.56')

h2= Host(hostname='h2',ip_addr='192.168.1.57',port=10000)

h3= Host(hostname='ubuntu',ip_addr='192.168.1.58',port=10000)

session.add_all([h1,h2,h3])

session.commit()

groups=session.query(Group).all()

g1=session.query(Group).first()

h2= session.query(Host).filter(Host.hostname=='h2').first()

h2.group= groups[1:-1]

print("===========>",h2.group)

#objs=#session.query(Host).join(Host.group).group_by(Group.name).all()

#objs=session.query(Host,func.count(Group.name)).\

#join(Host.group).group_by(Group.name).all()

#print("-->objs:",objs)

#print("++>",obj)

#obj.hostname= "test server"#session.delete(obj)

#objs= session.query(Host).filter(and_(Host.hostname.like("ub%"), Host.port > 20)).all()

session.commit()

View Code

877318-20160705094342514-468468429.png

877318-20160705094527967-1366535923.png

877318-20160705094723749-23222132.png

注意:

1 Session = sessionmaker(bind=engine,autoflush=False)

2 session.add添加数据到数据后,一定要session.commit()后才能增删改查,否则结果只能为none

3 session.query(Group).filter(Group.name=='g1').first() 注意有无first()的区别

再注意:

1 关于 session.add session.query session.commit的顺序问题?

就是说在同一个会话中, insert into table (xxxx)后,可以select * from xxx;可以查询到插入的数据,只是不能在其他会话,比如我另开一个客户端去连接数据库不能查询到刚刚插入的数据。

这个数据已经到数据库。值是数据库吧这个数据给锁了。只有插入数据的那个session可以查看到,其他的session不能查看到,可以理解提交并解锁吧。

2 第三张表必须利用table创建吗?NO

3 联合唯一

4 一对多的第二个例子,如何理解去掉第一个commit后就报错的现象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值