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
.html
from
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 一. ...
随机推荐
- iOS AFNetworking 详解
1. 很不错的介绍 http://m.blog.csdn.net/blog/jackljf/38736625
- c++中经常需要访问对象中的成员的三种方式
可以有3种方法: 通过对象名和成员运算符访问对象中的成员; 通过指向对象的指针访问对象中的成员; 通过对象的引用变量访问对象中的成员. 一.通过对象名和成员运算符访问对象中的成员 例如在程序中可以写出 ...
- 十分钟搭建自己的hadoop2/CDH4集群
版本及准备 我部署的是hadoop-2.0.0-cdh4.2.0.tar.gz,下载地址为http://archive.cloudera.com/cdh4/cdh/4/hadoop-2.0.0-cdh ...
- Thinkphp交友手机首页简明前台、后台
先来说下后台吧,后台要写后台模板-V,后台控制器-C 后台模板如下代码: <!DOCTYPE html> <html> <head> <meta charse ...
- Beans(dp,两次dp)
Beans Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- XSS第二节,XSS左邻右舍
昨天的文章中引用了OWASP2013年的江湖排名,今天来看一下TOP中XSS的左邻右舍都是谁,先看一下他们的大名,再进一步介绍 [以下主要翻译自https://www.owasp.org/index. ...
- [Hapi.js] Extending the request with lifecycle events
Instead of using middlware, hapi provides a number of points during the lifecycle of a request that ...
- Servlet实现Session
(1)首先看一下项目的结构 是在tomcat--webaps下的myWebSites项目 在myWebSites下有仅仅有WEB-INF目录 在WEB-INF目录中有 一下目录(在classes目录 ...
- Python模块学习笔记— —time与datatime
Python提供了多个内置模块用于操作日期时间.像calendar,time,datetime.首先对time模块中最经常使用的几个函数作一个介绍,它提供的接口与C标准库time.h基本一致.然后再介 ...
- Git 笔记二-Git安装与初始配置
git 笔记二-Git安装与初始配置 Git的安装 由于我日常生活和工作基本上都是在Windows上,因此此处只说windows上的安装.Windows上的安装和其他程序一样,只需要到http://g ...