Python 第十一篇:开发堡垒机
一:SqlAlchemy ORM
ORM:Object Relational Mapping 对象关系映射是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换
SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果:
建立在SQL AQI至上,不需要写原生SQL语句,是将对象封装并转成原生语句
Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
MySQL-Python #适用于python 2使用MySQL-python模块 mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql #适用于python 3,因为python 3里面的mysql模块变为pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector #使用mysql connector连接数据库 mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle #连接到oracle数据库 oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html
1、使用 sqlalchemy + pymysql创建表:
import pymysql from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() #创建user和color两个表,metadata封装语句 user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test", max_overflow=5) #连接到数据库,最大连接池5个 metadata.create_all(engine) #创建数据库
2、增加数据:
import pymysql from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test", max_overflow=5) conn = engine.connect() sql = user.insert().values(id=1,name='wu') #id可以不写,会自增 conn.execute(sql) conn.close()
数据库验证:
3、删除数据:
#/usr/bin/env python # -*- coding:utf-8 -*- import pymysql from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test", max_overflow=5) conn = engine.connect() sql1 = user.delete().where(user.c.id == 1) #匹配id为1 sql2 = user.delete().where(user.c.name == 'li') #匹配条件name为li conn.execute(sql1) #执行语句 conn.execute(sql2) conn.close()
4、改数据:
import pymysql from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test", max_overflow=5) conn = engine.connect() #sql1 = user.insert().values(name="zhang") #添加数据 sql1 = user.update().where(user.c.name == 'zhang').values(name='jack') #匹配套件并改数据 conn.execute(sql1) conn.close()
5、查数据:
#/usr/bin/env python # -*- coding:utf-8 -*- import pymysql from sqlalchemy import create_engine, select,Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) color = Table('color', metadata, Column('id', Integer, primary_key=True), Column('name', String(20)), ) engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test", max_overflow=5) conn = engine.connect() sql = select([user,]) res = conn.execute(sql) print(res.fetchall()) conn.close()
实际使用方法介绍:
创建表并插入数据:
#/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一个SqlORM 基类 engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test",echo=True) class Host(Base): __tablename__ = 'hosts' 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) Base.metadata.create_all(engine) #创建所有表结构 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 session = SessionCls() h1 = Host(hostname='localhost',ip_addr='127.0.0.1') h2 = Host(hostname='Centos',ip_addr='192.168.10.254',port=2021) session.add_all([h1,h2]) session.commit() #提交
查询并更改数据:
#/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一个SqlORM 基类 engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test",echo=True) class Host(Base): __tablename__ = 'hosts' 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) Base.metadata.create_all(engine) #创建所有表结构 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 session = SessionCls() h1 = Host(hostname='localhost',ip_addr='127.0.0.1') h2 = Host(hostname='Centos',ip_addr='192.168.10.254',port=2021) session.add_all([h1,h2]) #session.rollback() #h3 = Host(hostname='ubuntu2',ip_addr='192.168.2.244',port=20000) #session.add(h3) #session.add_all( [h1,h2]) #h2.hostname = 'ubuntu_test' #只要没提交,此时修改也没问题 res = session.query(Host).filter(Host.hostname.in_(['ubuntu2','localhost'])).first() #all所有,first第一个,last最后一个 #res.hostname = "test hostname" #将查到的数据改值 session.delete(res) #删除查询到的数据 session.commit() #提交
ORM 外键关联多对多: 一个组可以包含多个主机,一个主机也可以在多个组,即一个主机可以在多个组里面,如下:
class Parent(Base): #父类 __tablename__ = 'parent' id = Column(Integer, primary_key=True) children = relationship("Child") class Child(Base): #子类 __tablename__ = 'child' #定义表名称 id = Column(Integer, primary_key=True) #id的值类型 parent_id = Column(Integer, ForeignKey('parent.id')) #关联父类的'parent.id即可完成与父类的外键关联
测试;
sqlalchemy无法在已经存在的表里面增加新的字段,因此可以将表删除重新创建,或自己使用原生SQL语句创建,也可以使用sqlalchemy的三方工具,我们这里将以前的表删除再重建:
mysql> drop tables hosts;
Query OK, 0 rows affected (0.22 sec)
Pyhton 代码:
#/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy import create_engine,ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一个SqlORM 基类 engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test",echo=True) class Host(Base): __tablename__ = 'hosts' 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')) class Group(Base): __tablename__ = 'group' id = Column(Integer,primary_key=True) name = Column(String(64),unique=True,nullable=False) child_id = Column(Integer)
Base.metadata.create_all(engine) #创建所有表结构
if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 session = SessionCls() session.commit() #提交
验证:
mysql> desc hosts; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | hostname | varchar(64) | NO | UNI | NULL | | | ip_addr | varchar(128) | NO | UNI | NULL | | | port | int(11) | YES | | NULL | | | group_id | int(11) | YES | MUL | NULL | | +----------+--------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec)
#group_id 行的Key的值是Mul
查看group表:
mysql> desc test.group; +----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(64) | NO | UNI | NULL | | | child_id | int(11) | YES | | NULL | | +----------+-------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec)
创建关联的数据:
#/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy import create_engine,ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一个SqlORM 基类 engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test",echo=True) class Host(Base): __tablename__ = 'hosts' 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')) class Group(Base): __tablename__ = 'group' id = Column(Integer,primary_key=True) name = Column(String(64),unique=True,nullable=False) child_id = Column(Integer) Base.metadata.create_all(engine) #创建所有表结构 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 session = SessionCls() g3 = Group(name='g3') session.add_all([g3,]) h1 = Host(hostname='localhost',ip_addr='1.1.1.1',group_id=g3.id) #由于数据库还没有g3的内容,所以这样关联不成功 session.add_all([h1,]) session.commit() #提交
更改关联数据:
#/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy import create_engine,ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker Base = declarative_base() #生成一个SqlORM 基类 engine = create_engine("mysql+pymysql://root:zhang@123@localhost:3306/test",echo=True) class Host(Base): __tablename__ = 'hosts' 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')) class Group(Base): __tablename__ = 'group' id = Column(Integer,primary_key=True) name = Column(String(64),unique=True,nullable=False) child_id = Column(Integer) Base.metadata.create_all(engine) #创建所有表结构 if __name__ == '__main__': SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 session = SessionCls() g3 = session.query(Group).filter(Group.name=='g3').first() #查到一个已经存在的组 h = session.query(Host).filter(Host.hostname=='localhost').update({'group_id': g3.id}) #查到一个主机的信息并更新其group_id为上一步查到的组的id,即完成了外键的管理 session.commit() #提交