python之路-SQLAlchemy
SQLAchemy
SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
安装:
pip3 install SQLAlchemy
MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.htmlfrom sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5) # 执行SQL# cur = engine.execute(# "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)"# ) # 新插入行自增ID# cur.lastrowid # 执行SQL# cur = engine.execute(# "INSERT INTO hosts (host, color_id) VALUES(%s, %s)",[('1.1.1.22', 3),('1.1.1.221', 3),]# ) # 执行SQL# cur = engine.execute(# "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)",# host='1.1.1.99', color_id=3# ) # 执行SQL# cur = engine.execute('select * from hosts')# 获取第一行数据# cur.fetchone()# 获取第n行数据# cur.fetchmany(3)# 获取所有数据# cur.fetchall()使用 ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 所有组件对数据进行操作。根据类创建对象,对象转换成SQL,执行SQL。
创建表单
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5) #此处必须是双引号
Base = declarative_base()
# 创建单表
class Users(Base):
__tablename__ = 'users'
#此处就是创建表的表名
id = Column(Integer, primary_key=True)
#此处创建了三列
name = Column(String(32))
extra = Column(String(16))
__table_args__ = (
UniqueConstraint('id', 'name', name='uix_id_name'), #创建外建
Index('ix_id_name', 'name', 'extra') #创建索引
)
def __repr__(self):
#这个函数的作用是打印时期作用
#直接print(ret)
#就可以看到想要的结果。
temp = '%s-%s-%s' % (self.id, self.name, self.extra)
return temp
# 一对多
class Favor(Base):
__tablename__ = 'favor'
nid = Column(Integer, primary_key=True)
caption = Column(String(50), default='red', unique=True)
class Person(Base):
__tablename__ = 'person'
nid = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=True)
favor_id = Column(Integer, ForeignKey("favor.nid"))
# 多对多
class Group(Base):
__tablename__ = 'group'
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True, nullable=False)
class Server(Base):
__tablename__ = 'server'
id = Column(Integer, primary_key=True, autoincrement=True)
hostname = Column(String(64), unique=True, nullable=False)
port = Column(Integer, default=22)
class ServerToGroup(Base):
__tablename__ = 'servertogroup'
nid = Column(Integer, primary_key=True, autoincrement=True)
server_id = Column(Integer, ForeignKey('server.id')) #必须要有约束,就是外键
group_id = Column(Integer, ForeignKey('group.id'))
def init_db():
Base.metadata.create_all(engine)
#创建所有表
def drop_db():
Base.metadata.drop_all(engine)
#删除所有表
操作表
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5) Base = declarative_base() # 创建单表
class Users(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(32))
extra = Column(String(16)) __table_args__ = (
UniqueConstraint('id', 'name', name='uix_id_name'),
Index('ix_id_name', 'name', 'extra'),
) def __repr__(self):
return "%s-%s" %(self.id, self.name) # 一对多
class Favor(Base):
__tablename__ = 'favor'
nid = Column(Integer, primary_key=True)
caption = Column(String(50), default='red', unique=True) def __repr__(self):
return "%s-%s" %(self.nid, self.caption) class Person(Base):
__tablename__ = 'person'
nid = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=True)
favor_id = Column(Integer, ForeignKey("favor.nid"))
# 与生成表结构无关,仅用于查询方便
favor = relationship("Favor", backref='pers') #此处的作用就是联表,会把favor表中的数据读出来,不用我们去写联表语句。必须与关联的表中有foreignkey才可以。
# backref的作用就是在favor表中加了一个pers的字段,.pers就表示与favor相关的所有信息 #正向查询
ret = session.query(Person)
print(ret)
for obj in ret:
print(obj.nid,obj.name,obj.favor_id,obj.favor.captiom) # 反向查询
# obj = session.query(Group).filter(Group.caption =='DBA').first()
# print(obj.nid)
# print(obj.caption)
# print(obj.uuu)
#通过查找Group中在DBA组的成员,如果relationship中的backref指定uuu,那么,.uuu就把realtionship所关联表中的所有在DBA中的成员列出来。 # 多对多
class ServerToGroup(Base):
__tablename__ = 'servertogroup'
nid = Column(Integer, primary_key=True, autoincrement=True)
server_id = Column(Integer, ForeignKey('server.id'))
group_id = Column(Integer, ForeignKey('group.id'))
group = relationship("Group", backref='s2g')
server = relationship("Server", backref='s2g') class Group(Base):
__tablename__ = 'group'
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True, nullable=False)
port = Column(Integer, default=22)
# group = relationship('Group',secondary=ServerToGroup,backref='host_list') class Server(Base):
__tablename__ = 'server' id = Column(Integer, primary_key=True, autoincrement=True)
hostname = Column(String(64), unique=True, nullable=False) def init_db():
Base.metadata.create_all(engine) def drop_db():
Base.metadata.drop_all(engine) Session = sessionmaker(bind=engine) #如果想操作数据库必须要创建这个session
session = Session()
增
obj = Users(name="alex0", extra='sb') 增加一条数据
session.add(obj)
session.add_all([ 批量增加
Users(name="alex1", extra='sb'),
Users(name="alex2", extra='sb'),
])
session.commit()
删
session.query(Users).filter(Users.id > 2).delete() 如果想用and的话,就在〉2后面加,然后再跟条件
session.commit()
改
session.query(Users).filter(Users.id > 2).update({"name" : ""})
session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + ""}, synchronize_session=False) 字符串相加
session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate") 数字相加
session.commit()
查
ret = session.query(Users).all() 不加.all()print(ret)就会看到执行语句
如果想查看的话,可以执行:
print(ret[0].name) 因为ret是个列表,表中有几列,列表中就会有几个元素。
ret = session.query(Users.name, Users.extra).all()
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter_by(name='alex').first()
其他:
# 条件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all() 在这个范围
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() 波浪号代表非
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(
or_(
Users.id < 2,
and_(Users.name == 'eric', Users.id > 3),
Users.extra != ""
)).all() # 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all() # 限制
ret = session.query(Users)[1:2] # 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all() # 分组
from sqlalchemy.sql import func ret = session.query(Users).group_by(Users.extra).all()
ret = session.query(
func.max(Users.id),
func.sum(Users.id),
func.min(Users.id)).group_by(Users.name).all() ret = session.query(
func.max(Users.id),
func.sum(Users.id),
func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all() # 连表 ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all() ret = session.query(Person).join(Favor).all() 此处的join默认是inner join ret = session.query(Person).join(Favor, isouter=True).all() outer表示leftjoin # 组合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all() 会去重 q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all() 不会去重
多对多的操作:
多对多连表操作
需求以及数据库结构
需求:
三张表:
- 主机表:包括nid hostname port ip
- 管理员表:包括:nid username
- 主机对应管理员表: nid 主机id,管理员id
一个管理员帐号(比如root),可以关联多台服务器,一个服务器也可以有多个管理员帐号
先来看下数据结构吧:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
engine = create_engine("mysql+pymysql://root:7ujm8ik,@192.168.4.193:3306/testsql?charset=utf8", max_overflow=5)
Base = declarative_base()
#多对多
class HostToHostUser(Base):
__tablename__ = 'host_to_host_user'
id = Column(Integer, primary_key=True,autoincrement=True)
host_id = Column(Integer,ForeignKey('host.id'))
host_user_id = Column(Integer,ForeignKey('host_user.nid'))
#多对多操作
host = relationship('Host',backref='h')#backref='h'表示host表自动生成某种关联关系,这个关系就成为‘h’关系,只要下边某个表中的backref也指明了这个关系‘h’,那么host表就会与该表形成关联,基于'h'关系,这是道不清理不明的一种关系
host_user = relationship('HostUser',backref='u')#backref='u'表示host_user表自动生成某种关联关系,只要下边某个表中的backref也指明了这个关系‘u‘,那么host_user表就会与该表形成关联,基于'u'关系
(如果某张表中写了关联关系,关系表中就可以不用写了)
#查询方法:host_obj = session.query(Host).filter(Host.hostname =='c1').first()
print(host_obj.host_user)
class Host(Base):
__tablename__ = 'host'
nid = Column(Integer, primary_key=True,autoincrement=True)
hostname = Column(String(32))
port = Column(String(32))
ip = Column(String(32))
####最简单的方式,添加此行就行(另外一种方法,可以将关系放在某张表中):
host_user=relationship('HostUser',secondary=HostToHostUser.__table__,backref='h')#这里backref指明了‘h’关系,那么host表就会与host_user表生成关联关系
#格式:表名(本类是host表,这里写要跟host关联的表)=relationship('对象名(本类是host表,这里写要跟host关联的表的对象名)', secondary=中间表的对象名, backref=关联关系'h')
class HostUser(Base):
__tablename__ = 'host_user'
nid = Column(Integer, primary_key=True,autoincrement=True)
username = Column(String(32))
def init_db():
Base.metadata.create_all(engine)
# init_db()
def drop_db():
Base.metadata.drop_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
#======多对多操作
# session.add_all([
# Host(hostname='c1',port='22',ip='1.1.1.1'),
# Host(hostname='c2',port='22',ip='1.1.1.2'),
# Host(hostname='c3',port='22',ip='1.1.1.3'),
# Host(hostname='c4',port='22',ip='1.1.1.4'),
# Host(hostname='c5',port='22',ip='1.1.1.5'),
# ])
# session.commit()
# session.add_all([
# HostUser(username='root'),
# HostUser(username='db'),
# HostUser(username='nb'),
# HostUser(username='sb'),
# ])
# session.commit()
# session.add_all([
# HostToHostUser(host_id=1,host_user_id=1),
# HostToHostUser(host_id=1,host_user_id=2),
# HostToHostUser(host_id=1,host_user_id=3),
# HostToHostUser(host_id=2,host_user_id=2),
# HostToHostUser(host_id=2,host_user_id=4),
# HostToHostUser(host_id=2,host_user_id=3),
# ])
# session.commit()
虚拟关系的查询
需求:查询主机C1的管理员帐号
# 1.反向查找,查询host表中c1的信息,会得到一个对象,对象中存在一个已经设置好的虚拟关系:h
host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
#2.正向查找,遍历对象属性
for item in host_obj.h:
print(item.host_user.username)
(整个过程经历了一个循环,通过host找到hosttouser,在通过hosttouser中的backref的h,列出所有与c1有关的数据)
结果:
root
db
nb
注意:多对多的话,正反查询都是遍历对象中的属性
同一需求最简单的方式
需求还是同上:查询主机C1的管理员帐号
需要在两张表的一张表中加一条host_user=relationship('HostUser',secondary=HostToHostUser.__table__,backref='h'),我加到了host表中
#最简单的查询方式:
host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
print(host_obj.host_user)
for item in host_obj.host_user:
print(item.username)
结果:
[<__main__.HostUser object at 0x103778710>, <__main__.HostUser object at 0x103778d68>, <__main__.HostUser object at 0x103778e10>]
root
db
nb
python之路-SQLAlchemy的更多相关文章
- Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...
- python 之路,Day11 (下)- sqlalchemy ORM
python 之路,Day11 - sqlalchemy ORM 本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 1. ORM ...
- Python 之路:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
一.Memcached Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负债.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速 ...
- Python之路,Day12 - 那就做个堡垒机吧
Python之路,Day12 - 那就做个堡垒机吧 本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多 ...
- Python之路,Day10 - 异步IO\数据库\队列\缓存
Python之路,Day9 - 异步IO\数据库\队列\缓存 本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...
- Python之路,Day9 - 异步IO\数据库\队列\缓存
https://www.cnblogs.com/alex3714/articles/5248247.html http://www.cnblogs.com/wupeiqi/articles/51327 ...
- Python 之路
Python之路[第一篇]:Python简介和入门 Python之路[第二篇]:Python基础(一) Python之路[第三篇]:Python基础(二) Python之路[第四篇]:模块 Pytho ...
- Python之路【第一篇】python基础
一.python开发 1.开发: 1)高级语言:python .Java .PHP. C# Go ruby c++ ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...
- 20.Python笔记之SqlAlchemy使用
Date:2016-03-27 Title:20.Python笔记之SqlAlchemy使用 Tags:python Category:Python 作者:刘耀 博客:www.liuyao.me 一. ...
随机推荐
- poj 3616 Milking Time DP
题意:在给予的N个时间里,奶牛Bessie在M个时间段里进行产奶,但是每次产奶后都要休息R个时间 M个时间段里,分别有开始时间start和结束时间end,和该时间段里产奶的效率efficiency 求 ...
- JSTL核心标签库学习笔记
写的很简单,不一定会有用,如果想要详细的话,建议看API啊--- 不过在这里推荐一个地址,http://www.yiibai.com/jstl/ 希望对你们有帮助啊,很好的教材啊 1.<c:i ...
- JavaScript面向对象之类的继承
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- linux下的守护进程及会话、进程组
守护进程.会话.进程组网上有许多不错的资料.我也是网上搜罗了一堆,加上自己的理解.不敢说原创,只是写在这怕自己忘记罢了.才疏学浅,难免有错误,欢迎大家指正.下面这篇写很不错,大家可以去看看:http: ...
- WPF的数据绑定详细介绍
数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程. 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改. 数据绑定可能还意味着如果视觉元素中数据的 ...
- pyqt sender()学习
#!/usr/bin/python # -*- coding: utf-8 -*- # sender.py import sys from PyQt4 import QtGui, QtCore cla ...
- 虚拟机IOS开发环境搭建教程
来源:http://www.cnblogs.com/xiaoyaoju/archive/2013/05/21/3091171.html 安装条件: 硬件:一台拥有支持虚拟技术的64位双核处理器和2GB ...
- java 中打印调用栈
source-code: public class A { public A() {} private static void printStackTrace() { StackTra ...
- Entity Framework Code First主外键关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- struts2 实现过程和xml配置
实现过程: 当Web容器收到 请求(HttpServletRequest)它将请求传递给一个标准的的过滤链包括 (ActionContextCleanUp)过滤器,然后经过Other filters( ...