Python【day 11】:Python学习(sqlalchemy)

sqlalchemy 建表

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
#导入模块

metadata = MetaData() #新建实例

user = Table('user1', metadata,  #创建表1,表名是user1 #这里metadata类似于类的继承(Table继承metadata)
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键(默认自增)
    Column('name', String(20)),  #字段2 字段名字name 字符串类型 20个字节长度
)  #这个表配置了一下(表进行了对象的映射),这些最终会转换成sql语句取调mysql的api
# metadata定义了怎么讲上述对象转换成sql语句

color = Table('color1', metadata, #创建表2,表名是color1
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键(默认自增)
    Column('name', String(20)), #字段2 字段名字name 字符串类型 20个字节长度
)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test", max_overflow=5)
#创建数据库连接   mysql用户名:root mysql密码:123123  mysql主机ip:192.168.19.130  数据库实例名字:test

metadata.create_all(engine)  #如果表已经存在了,这句代码(创建引擎)可以不写,写了也没关系,只是不执行了
#创建上述2个表的结构

增加记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select

#导入模块

metadata = MetaData() #新建实例

user = Table('user2', metadata,  #创建表1,表名是user2
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
    Column('name', String(20)),  #字段2 字段名字name 字符串类型 20个字节长度
)

# color = Table('color2', metadata, #创建表2,表名是color1
#     Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
#     Column('name', String(20)), #字段2 字段名字name 字符串类型 20个字节长度
# )
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test", max_overflow=5)
#创建数据库连接   mysql用户名:root mysql密码:123123  mysql主机ip:192.168.19.130  数据库实例名字:test

conn = engine.connect()  #创建一个游标(增删改查必须先创建游标)

metadata.create_all(engine) ##如果表已经存在了,这句代码(创建引擎)可以不写,写了也没关系,只是不执行了
#如果不存在,就是创建表

sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall()) #[(7, 'seven'), (9, 'jack')]

# 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)  #原生sql
result=conn.execute(user.insert(),{'id':12,'name':'seven'})  #往表"user2"中新增一条记录
# result=conn.execute(user.insert(),{'name':'seven'})  #主键是自增的,id可以不写,默认从1开始
# sql= user.insert(),{'id':9,'name':'seven'}  #分开执行 ,会报错
# conn.execute(sql)
# print(result.fetchall())

sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall()) #[(7, 'seven'), (9, 'jack'), (12, 'seven')]

conn.close() #关闭游标

删除记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select
#导入模块

metadata = MetaData() #新建实例

user = Table('user2', metadata,  #创建表1,表名是user1
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
    Column('name', String(20)),  #字段2 字段名字name 字符串类型 20个字节长度
)

# color = Table('color2', metadata, #创建表2,表名是color1
#     Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
#     Column('name', String(20)), #字段2 字段名字name 字符串类型 20个字节长度
# )
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test", max_overflow=5)
#创建数据库连接   mysql用户名:root mysql密码:123123  mysql主机ip:192.168.19.130  数据库实例名字:test

conn = engine.connect()  #创建一个游标

metadata.create_all(engine)

# 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)  #原生sql
# conn.execute(user.insert(),{'id':8,'name':'seven'})  #往表"user2"中新增一条记录
sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall())  #[(7, 'seven'), (9, 'jack'), (10, 'seven')]

sql = user.delete().where(user.c.id > 9)  #从表"user2"中删除id>7的记录 这里user.c.id中的c是固定写法,记下
conn.execute(sql) #通过游标执行sql语句

sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall()) #[(7, 'seven'), (9, 'jack')]

conn.close() #关闭游标

修改记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select
#导入模块

metadata = MetaData() #新建实例

user = Table('user2', metadata,  #创建表1,表名是user1
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
    Column('name', String(20)),  #字段2 字段名字name 字符串类型 20个字节长度
)

# color = Table('color2', metadata, #创建表2,表名是color1
#     Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
#     Column('name', String(20)), #字段2 字段名字name 字符串类型 20个字节长度
# )
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test", max_overflow=5)
#创建数据库连接   mysql用户名:root mysql密码:123123  mysql主机ip:192.168.19.130  数据库实例名字:test

conn = engine.connect()  #创建一个游标

metadata.create_all(engine)

sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall())  #[(7, 'seven'), (9, 'jack'), (12, 'seven')]

# 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)  #原生sql
# conn.execute(user.insert(),{'id':8,'name':'seven'})  #往表"user2"中新增一条记录
# sql = user.delete().where(user.c.id > 7)  #从表"user2"中删除id>7的记录 这里user.c.id中的c是固定写法,记下
sql = user.update().where(user.c.id == 9).values(name='jack1')
#将id=9的这一条记录的name字段改成"jack"
result = conn.execute(sql) #通过游标执行sql语句

sql = select([user, ])
result = conn.execute(sql)
print(result.fetchall()) #[(7, 'seven'), (9, 'jack1'), (12, 'seven')]

conn.close() #关闭游标

查询记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select
#导入模块

metadata = MetaData() #新建实例

user = Table('user2', metadata,  #创建表1,表名是user1
    Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
    Column('name', String(20)),  #字段2 字段名字name 字符串类型 20个字节长度
)

# color = Table('color2', metadata, #创建表2,表名是color1
#     Column('id', Integer, primary_key=True), #字段1 字段名字是id 整数 主键
#     Column('name', String(20)), #字段2 字段名字name 字符串类型 20个字节长度
# )
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test", max_overflow=5)
#创建数据库连接   mysql用户名:root mysql密码:123123  mysql主机ip:192.168.19.130  数据库实例名字:test

conn = engine.connect()  #创建一个游标

metadata.create_all(engine)

# 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)  #原生sql
# conn.execute(user.insert(),{'id':8,'name':'seven'})  #往表"user2"中新增一条记录
# sql = user.delete().where(user.c.id > 7)  #从表"user2"中删除id>7的记录 这里user.c.id中的c是固定写法,记下
# sql = user.update().where(user.c.id == 9).values(name='jack')
# #将id=9的这一条记录的name字段改成"jack"

#1查询所有记录
sql = select([user, ])  #查询表"user2"的所有记录  原生sql:select * from user2  需要先导入select模块
result = conn.execute(sql) #通过游标执行sql语句
print(result.fetchall())  #[(7, 'seven'), (9, 'jack')]   列表中元组的形式(id,name)
#输出所有的记录

sql = select([user.c.id, ])  #查询表"user2"的id字段所有记录 原生sql:select id from user2
result = conn.execute(sql) #通过游标执行sql语句
print(result.fetchall()) #[(7,), (9,), (12,)]

#2排序
sql = select([user,]).order_by(user.c.id) #按照id顺序排列 #原生sql:select id from user2 oeder by id
result = conn.execute(sql) #通过游标执行sql语句
print(result.fetchall()) #[(7, 'seven'), (9, 'jack1'), (12, 'seven')]

#聚合统计 group by
sql = select([user,]).group_by(user.c.name) #按照name进行聚合统计
#原生sql:select count(*) from user2 group by name
result = conn.execute(sql) #通过游标执行sql语句
print(result.fetchall()) #[(9, 'jack1'), (7, 'seven')]

#3多表查询
# sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id)

conn.close() #关闭游标

 

建表2-新插入记录

__author__ = 'Administrator'
#-*- 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 基类(相当于前面的metedata)

# engine = create_engine("mysql+mysqldb://root@localhost:3306/test",echo=False)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       # max_overflow=5,echo=True)
                       max_overflow=5,echo=False)
#这里的echo=True可以显示建表过程
#这里的echo=False不会显示建表过程

class Host(Base): #继承基类  (创建一个表的映射)
    __tablename__ = 'hosts'   #定义表名"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') #id是主键,不写就是自增;port不写就是默认22
    h2 = Host(hostname='ubuntu',ip_addr='192.168.2.243',port=20000) #插入记录1
    h3 = Host(hostname='ubuntu2',ip_addr='192.168.2.244',port=20000) #插入记录2
    #session.add(h3)
    session.add_all( [h2,h3]) #执行插入操作
    #h2.hostname = 'ubuntu_test' #只要没提交,此时修改也没问题
    #session.rollback()
    session.commit() #提交 必须commit才能生效
    res = session.query(Host).filter(Host.hostname.in_(['ubuntu','ubuntu2'])).all()
    #原生sql  select * from hosts where hostname in("ubuntu","ubuntu2");
    print(res)
    #[<__main__.Host object at 0x000000000361BDD8>, <__main__.Host object at 0x000000000361B898>]

 

建表2-回滚

__author__ = 'Administrator'
#-*- 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+mysqldb://root@localhost:3306/test",echo=False)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       # max_overflow=5,echo=True)
                       max_overflow=5,echo=False)
#这里的echo=True可以显示建表过程
#这里的echo=False不会显示建表过程

class Host(Base): #继承基类
    __tablename__ = 'hosts'   #定义表名"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='ubuntu3',ip_addr='192.168.2.243',port=20000) #插入记录1
    h3 = Host(hostname='ubuntu4',ip_addr='192.168.2.244',port=20000) #插入记录2
    #session.add(h3)
    session.add_all( [h2,h3]) #执行插入操作
    #h2.hostname = 'ubuntu_test' #只要没提交,此时修改也没问题
    session.rollback()   #提交之前先回滚了,插入操作失效
    session.commit() #提交 必须commit才能生效
    res = session.query(Host).filter(Host.hostname.in_(['ubuntu','ubuntu2'])).all()
    #原生sql  select * from hosts where hostname in("ubuntu","ubuntu2");
    print(res)
    #[<__main__.Host object at 0x000000000361BDD8>, <__main__.Host object at 0x000000000361B898>]

 

建表03

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

# engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
                       # max_overflow=5,echo=False)

Base = declarative_base()



class User(Base):
    __tablename__ = 'users1'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# # ########## 增 ##########
# u = User(id=2, name='sb')
# session.add(u)
# session.add_all([
#     User(id=3, name='sb'),
#     User(id=4, name='sb')
# ])
session.commit()

 

新建记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

# engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
                       # max_overflow=5,echo=False)

Base = declarative_base()

class User(Base): #继承类Base
    __tablename__ = 'users1'  #定义表名
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# # ########## 增 ##########
u = User(id=2, name='sb') #先插入一条记录
session.add(u)
session.add_all([
    User(id=3, name='sb'),  ##再插入2条记录
    User(id=4, name='sb')
])
session.commit() #必须提交才能生效
##原生sql insert into users1("id","name") values (2,"sb");
##原生sql insert into users1("id","name") values (3,"sb");
##原生sql insert into users1("id","name") values (4,"sb");

 

删除记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

# engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
                       # max_overflow=5,echo=False)

Base = declarative_base()

class User(Base): #继承类Base
    __tablename__ = 'users1'  #定义表名
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# # # ########## 增 ##########
# u = User(id=2, name='sb') #先插入一条记录
# session.add(u)
# session.add_all([
#     User(id=3, name='sb'),  ##再插入2条记录
#     User(id=4, name='sb')
# ])
##原生sql insert into users1("id","name") values (2,"sb");
##原生sql insert into users1("id","name") values (3,"sb");
##原生sql insert into users1("id","name") values (4,"sb");
#  session.commit() #必须提交才能生效

# ########## 删除 方法1##########
session.query(User).filter(User.id > 2).delete()
#将id大于2的记录删除
# 原生sql   delete from users1 where id >2;
session.commit() #必须提交才能生效

# ########## 删除 方法2##########
obj = session.query(User).filter(User.id > 2).all()  #删除所有符合条件的
# obj = session.query(User).filter(User.id > 2).first() #删除所有符合条件的第一条
# obj = session.query(User).filter(User.id > 2).last() #删除所有符合条件的最后一条
#1先将id大于2的记录查出来
# 原生sql   delete from users1 where id >2;
session.delete(obj)  #2再将查出来的记录删除
session.commit() #必须提交才能生效

修改记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

# engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
                       # max_overflow=5,echo=False)

Base = declarative_base()

class User(Base): #继承类Base
    __tablename__ = 'users1'  #定义表名
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# # # ########## 增 ##########
# u = User(id=2, name='sb') #先插入一条记录
# session.add(u)
# session.add_all([
#     User(id=3, name='sb'),  ##再插入2条记录
#     User(id=4, name='sb')
# ])
##原生sql insert into users1("id","name") values (2,"sb");
##原生sql insert into users1("id","name") values (3,"sb");
##原生sql insert into users1("id","name") values (4,"sb");
#  session.commit() #必须提交才能生效

# # ########## 删除 ##########
# session.query(User).filter(User.id > 2).delete()
# #将id大于2的记录删除
# # 原生sql   delete from users1 where id >2;
# session.commit() #必须提交才能生效

# # ########## 修改 方法1 ##########
# # session.query(User).filter(User.id >1 ).update({'name' : "jack3"})  #可以一次修改多条
# session.query(User).filter(User.id == 2 ).update({'name' : "jack3"})  #一次修改一条
# session.commit()

# ########## 修改 方法2 ##########
obj = session.query(User).filter(User.id == 2 ).all()  #先把要修改的记录查出来
obj.name = "jack4"  #再进行修改
session.commit()

 

查询记录

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


__author__ = 'Administrator'
#-*- coding:utf-8 -*-


from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

# engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
                       # max_overflow=5,echo=False)

Base = declarative_base()

class User(Base): #继承类Base
    __tablename__ = 'users1'  #定义表名
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    def __repr__(self):  #查询的时候,可以显示查询的结果记录
        return  "<id=%s,name=%s>" %(self.id,self.name)


# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# # # ########## 增 ##########
# u = User(id=2, name='sb') #先插入一条记录
# session.add(u)
# session.add_all([
#     User(id=3, name='sb'),  ##再插入2条记录
#     User(id=4, name='sb')
# ])
##原生sql insert into users1("id","name") values (2,"sb");
##原生sql insert into users1("id","name") values (3,"sb");
##原生sql insert into users1("id","name") values (4,"sb");
#  session.commit() #必须提交才能生效

# # ########## 删除 ##########
# session.query(User).filter(User.id > 2).delete()
# #将id大于2的记录删除
# # 原生sql   delete from users1 where id >2;
# session.commit() #必须提交才能生效

# # ########## 修改 ##########
# # session.query(User).filter(User.id >1 ).update({'name' : "jack3"})  #可以一次修改多条
# session.query(User).filter(User.id == 2 ).update({'name' : "jack3"})  #一次修改一条
#原生sql update users1 set name = "jack3" where id =2;
# session.commit()

# ########## 查 ##########
# ret = session.query(User).filter_by(name='jack2').first() #显示第一条符合要求的
# print(ret)  #<__main__.User object at 0x000000000361C5F8>

# ret = session.query(User).filter_by(name='jack2').all() #显示所有符合要求的
# print(ret) #[<__main__.User object at 0x00000000035FCE10>, <__main__.User object at 0x000000000361D0B8>]
#查到2条
#原生sql select * from users1 where name ="jack2";

# #3 in关键字
# ret = session.query(User).filter(User.name.in_(['jack2','jack3'])).all()
# print(ret)  #查到3条
# #原生sql select * from users1 where name in ("jack2","jack3");

# #4 排序 order by
ret = session.query(User).order_by(User.id).all()
print(ret) #[<id=2,name=jack3>, <id=3,name=jack2>, <id=4,name=jack2>]
# #原生sql select * from users1 order by id;  默认升序

# #5 排序 order by 区间
# ret = session.query(User).order_by(User.id)[2:3]
# print(ret)
#原生sql select * from users1 where id between 2 and 3 order by id;  默认升序
# session.commit()

 

外键

__author__ = 'Administrator'
#-*- coding:utf-8 -*-

from sqlalchemy import Table, Column, Integer, ForeignKey,create_engine
from sqlalchemy.orm import relationship
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    # children = relationship("Child")
    children = relationship("Child", backref="parent")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    #定义外键 child表的parent_id是外键,对应parent表的主键id

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

ret = session.query(Child).filter_by(name='jack2').all() #显示所有符合要求的
print(ret)

 

外键——一对多

__author__ = 'Administrator'
#-*- coding:utf-8 -*-


# 外键引用relationship()

#!/usr/bin/env python3
#coding:utf8
#导入所需模块
from sqlalchemy import create_engine,func
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from  sqlalchemy.orm import sessionmaker,relationship
#生成sqlorm基类
Base = declarative_base()
#创建数据库连接
# engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)

#目的是一个人可以拥有多本书,那么在数据库里的一对多关系

class User(Base):
    #表名
    __tablename__ = 'user'
    #id字段
    id = Column(String(20), primary_key=True)
    #名字字段
    name = Column(String(20))
    # 一对多:#内容不是表名而是定义的表结构名字
    books = relationship('Book')
class Book(Base):
    #表名
    __tablename__ = 'book'
    #id字段
    id = Column(String(20), primary_key=True)
    #名字字段
    name = Column(String(20))
    # “多”的一方的book表是通过外键关联到user表的:
    #ForeignKey是外键 关联user表的id字段
    #"book"表的"user_id"是外键,他对应"user"表的主键"id"
    user_id = Column(String(20), ForeignKey('user.id'))  #定义外键
#创建所需表
Base.metadata.create_all(engine)

if __name__ == '__main__':
    #绑定,生成会话
    SessionCls = sessionmaker(bind=engine)  #返回的是类
    session = SessionCls()  #实例
    #创建用户--新建2条记录
    liuyao = User(id='1',name='liuyao')
    ali=User(id='2',name='ali')
    #添加字段--将字段添加到session
    session.add_all([liuyao,ali])
    #提交
    session.commit()
    #创建白鹿原这本书,指定谁是拥有者
    Whitedeer = Book(id='1',name='White_deer',user_id = '1')
    #创建三体这本书,指定谁是拥有者
    Threebody = Book(id='2',name='Three_body',user_id = '2')
    #添加字段
    session.add_all([Whitedeer,Threebody])
    #提交
    session.commit()

 

外键-多对多

__author__ = 'Administrator'
#-*- coding:utf-8 -*-
#
# 多对多
#
# 建立一个双向一对多关系,“反向”是一个许多人,指定一个额外的relationship()函数
# 并连接两个使用relationship.back_populates参数 简单来说, relationship函数是sqlalchemy对关系之间提供的
# 一种便利的调用方式, backref参数则对关系提供反向引用的声明。
# 在最新版本的sqlalchemy中对relationship引进了back_populates参数。


from sqlalchemy import Column, Sequence, String, Integer, ForeignKey
from sqlalchemy import create_engine # 导入创建连接驱动
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relationship, backref
# 这个url可以用urlparse解析, 其中echo=True表示执行时显示sql语句
# engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5)
engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
#生成了declarative基类, 以后的model继承此类
Base = declarative_base()
class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    name = Column(String(64),unique=True,nullable=False)
    children = relationship("Child", back_populates="parent")  #双向关联,成对出现
class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    name = Column(String(64),unique=True,nullable=False)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates="children")  #双向关联,成对出现
Base.metadata.create_all(engine) #创建所有表结构
if __name__ == '__main__':
    SessionCls = sessionmaker(bind=engine)
    #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
    session = SessionCls()
    mama = Parent(id='1',name='mamaxx')  #添加2条记录
    baba = Parent(id='2',name='babaoo')
    session.add_all([mama,baba])
    session.commit() #提交
    onesb = Child(id='1',name='onesb',parent_id='2')
    twosb = Child(id='2',name='twosb',parent_id='2')
    session.add_all([onesb,twosb])
    session.commit() #提交

 

外键-多对多中间表

__author__ = 'Administrator'
#-*- coding:utf-8 -*-
#

from sqlalchemy import create_engine,func,Table,select
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from  sqlalchemy.orm import sessionmaker,relationship
Base = declarative_base() ##生成了declarative基类, 以后的model继承此类

#中间关系表(中间关系表的2个字段都是外键,分别对应其他2个表的主键,主键关系表本身由2个外键一同组成主键)
Host2Group = Table('host_2_group',Base.metadata,
               Column('host_id',ForeignKey('hosts.id'),primary_key=True),
               Column('group_id',ForeignKey('group1.id'),primary_key=True),
               )
# engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5)

engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test1",
                       max_overflow=5,echo=True)

conn = engine.connect()

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)

    groups = relationship('Group',  #关联group表,这里是类名
                      secondary= Host2Group, #关联中间关系表,这里也是类名
                      backref = 'host_list') #想要查看一个组包含多少主机,通过host_list调用,单向即可
    #想要看一个主机属于几个组,通过host_list调用
    #把表"group"作为一个对象,通过host_list来调用
    def __repr__(self):
        return  "<id=%s,hostname=%s, ip_addr=%s>" %(self.id,
                                                    self.hostname,
                                                    self.ip_addr)
class Group(Base):
    __tablename__ = 'group1'
    id = Column(Integer,primary_key=True)
    name = Column(String(64),unique=True,nullable=False)

Base.metadata.create_all(engine) #创建所有表结构 (这句代码至关重要)
if __name__ == '__main__':
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()
    h1 = Host(hostname='h3',ip_addr="1.23.22.11")
    h2 = Host(hostname='h4',ip_addr="1.23.22.111")
    session.add_all([h1,h2])  #创建2个主机
    session.commit()  #提交

    g1 = Group(name='g3')
    g2 = Group(name='g4')
    # g3 = Group(name='g3')
    # g4 = Group(name='g4')
    session.add_all([g1,g2])  #创建2个组
    session.commit()  #提交

    sql = select([Host2Group, ])
    result = conn.execute(sql)
    print(result.fetchall()) #[]

    # # 创建SQL语句,INSERT INTO "user" (host_id, group_id) VALUES (:host_id, :group_id)  #原生sql
    result=conn.execute(Host2Group.insert(),{'host_id':1,'group_id':'1'})  #往表"Host2Group"中新增一条记录
    result=conn.execute(Host2Group.insert(),{'host_id':2,'group_id':'1'})

    sql = select([Host2Group, ])
    result = conn.execute(sql)
    print(result.fetchall()) #[(1, 2), (2, 2)]

    conn.close() #关闭游标

 

外键-backref

__author__ = 'Administrator'
#-*- coding:utf-8 -*-
#

from sqlalchemy import Integer, ForeignKey, String, Column,create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship,sessionmaker

engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)

Base = declarative_base()

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

    addresses = relationship("Address", backref="user")
    def __repr__(self):  #查询的时候,可以显示查询的结果记录
        return  "<id=%s,name=%s>" %(self.id,self.name)


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    email = Column(String(50))
    user_id = Column(Integer, ForeignKey('user.id'))
    def __repr__(self):  #查询的时候,可以显示查询的结果记录
        return  "<id=%s,email=%s,user_id=%s>" %(self.id,self.email,self.user_id)

# 寻找Base的所有子类,按照子类的结构在数据库中生成对应的数据表信息
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

# session.add_all([
#     User(id=3, name='sb3'),  ##再插入2条记录
#     User(id=4, name='sb4')
# ])
#
# session.add_all([
#     Address(id=1, email='123@163.com',user_id=3),  ##再插入2条记录
#     Address(id=2, email='124@163.com',user_id=4)
# ])

#1如果没有19行的话,需要2条sql
# user = session.query(User).filter_by(name="sb3").first()
# print(user) #<id=3,name=sb3>
# # 假如没有relationship,我们只能像下面这样调用关系数据。
# ---先通过名字找到用户id 再通过用户id去另外一张表找email
#
# addresses = session.query(Address).filter_by(user_id=3).all()#再通过用户id去另外一张表找email
# print(addresses) #[<id=1,email=123@163.com,user_id=3>]


#2 加上19行 addresses = relationship("Address")#, backref="user")后
#  就只需要1步(一个sql),就可以查到另外一张表的所有字段--外键关联(相当于通过外键进行多表查询)
sql = session.query(User).filter_by(name="sb3").first()
print(sql.addresses)  #19行  #[<id=1,email=123@163.com,user_id=3>]
#这里的addresses指的是19行addresses = relationship("Address", backref="user") 最前面的addresses
#通过表A的字段(用户名字),查表B的字段(邮箱) 这里的addresses代指表B(地址表)

#3 注意,在上面的addresses属性中我们并没有定义backref属性,所以我们可以通过User对象获取所拥有的地址,
# 但是不能通过Address对象获取到所属的用户.
#我们当我们有从Address对象获取所属用户的需求时,backref参数就派上用场了。
# 大致原理应该就是sqlalchemy在运行时对Address对象动态的设置了一个指向所属User对象的属性,
# 这样就能在实际开发中使逻辑关系更加清晰,代码更加简洁了。
sql = session.query(Address).filter_by(email="124@163.com").first()
print(sql.user)  #19行 <id=4,name=sb4>  #这里的"user"指的是19行backref="user"后的user 这里的user代指表A(用户表)
#  就只需要1步,就可以查到另外一张表的所有字段--外键关联(相当于通过外键进行多表查询)
# 通过表b的邮箱,查到表b的user_id,通过user_id查到表A的id(就是表B的user_id)和name
#通过表B的字段(邮箱),查表A的字段(用户名字)

# http://www.zhihu.com/question/38456789

 

左连接

# __author__ = 'Administrator'
# #-*- coding:utf-8 -*-
#
# # http://stackoverflow.com/questions/38549/difference-between-inner-and-outer-joins
#
# #1左外连接
# # A    B
# # -    -
# # 1    3
# # 2    4
# # 3    5
# # 4    6
# #
# # select * from A LEFT OUTER JOIN B on A.a = B.b;  原生sql
# #
# # a |  b
# # --+-----
# # 1 | null
# # 2 | null
# # 3 |    3
# # 4 |    4
#
# # session.query(Host).join(Host.host_groups).filter(HostGroup.name=='t1').group_by("Host").all()
#
#
# # Examples
# #
# # Suppose you have two tables, with a single column each, and data as follows:
# #
# # A    B
# # -    -
# # 1    3
# # 2    4
# # 3    5
# # 4    6
# # Note that (1,2) are unique to A, (3,4) are common, and (5,6) are unique to B.
# #
# # Inner join
# #
# # An inner join using either of the equivalent queries gives the intersection of the two tables, i.e. the two rows they have in common.
# #
# # select * from a INNER JOIN b on a.a = b.b;
# # select a.*,b.*  from a,b where a.a = b.b;
# #
# # a | b
# # --+--
# # 3 | 3
# # 4 | 4
# # Left outer join
# #
# # A left outer join will give all rows in A, plus any common rows in B.
# #
# # select * from a LEFT OUTER JOIN b on a.a = b.b;
# # select a.*,b.*  from a,b where a.a = b.b(+);
# #
# # a |  b
# # --+-----
# # 1 | null
# # 2 | null
# # 3 |    3
# # 4 |    4
# # Right outer join
# #
# # A right outer join will give all rows in B, plus any common rows in A.
# #
# # select * from a RIGHT OUTER JOIN b on a.a = b.b;
# # select a.*,b.*  from a,b where a.a(+) = b.b;
# #
# # a    |  b
# # -----+----
# # 3    |  3
# # 4    |  4
# # null |  5
# # null |  6
# # Full outer join
# #
# # A full outer join will give you the union of A and B, i.e. all the rows in A and all the rows in B. If something in A doesn't have a corresponding datum in B, then the B portion is null, and vice versa.
# #
# # select * from a FULL OUTER JOIN b on a.a = b.b;
# #
# #  a   |  b
# # -----+-----
# #    1 | null
# #    2 | null
# #    3 |    3
# #    4 |    4
# # null |    6
# # null |    5
#
#
# 如何连接表?
#
#
#
# 复制代码 代码如下:
#
# from sqlalchemy import distinct
# from sqlalchemy.orm import aliased
#
#
# Friend = aliased(User, name='Friend')
#
# print session.query(User.id).join(Friendship, User.id == Friendship.user_id1).all()
# # 所有有朋友的用户
# print session.query(distinct(User.id)).join(Friendship, User.id == Friendship.user_id1).all()
# # 所有有朋友的用户(去掉重复的)
# print session.query(User.id).join(Friendship, User.id == Friendship.user_id1).distinct().all()
# # 同上
# print session.query(Friendship.user_id2).join(User, User.id == Friendship.user_id1).order_by(Friendship.user_id2).distinct().all()
# # 所有被别人当成朋友的用户
# print session.query(Friendship.user_id2).select_from(User).join(Friendship, User.id == Friendship.user_id1).order_by(Friendship.user_id2).distinct().all()
# # 同上,join 的方向相反,但因为不是 STRAIGHT_JOIN,所以 MySQL 可以自己选择顺序
# print session.query(User.id, Friendship.user_id2).join(Friendship, User.id == Friendship.user_id1).all()
# # 用户及其朋友
# print session.query(User.id, Friendship.user_id2).join(Friendship, User.id == Friendship.user_id1).filter(User.id < 10).all()
# # id 小于 10 的用户及其朋友
# print session.query(User.id, Friend.id).join(Friendship, User.id == Friendship.user_id1).join(Friend, Friend.id == Friendship.user_id2).all()
# # 两次 join,由于使用到相同的表,因此需要别名
# print session.query(User.id, Friendship.user_id2).outerjoin(Friendship, User.id == Friendship.user_id1).all()
# # 用户及其朋友(无朋友则为 None,使用左连接)

# http://www.jb51.net/article/49789.htm

 

左右连接、自连接

__author__ = 'Administrator'
#-*- coding:utf-8 -*-

__author__ = 'Administrator'
#-*- coding:utf-8 -*-
#

from sqlalchemy import create_engine,func,Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from  sqlalchemy.orm import sessionmaker,relationship
Base = declarative_base() ##生成了declarative基类, 以后的model继承此类

# engine = create_engine("mysql+mysqldb://liuyao:liuyao@121.42.195.15:3306/liuyao", max_overflow=5)

engine = create_engine("mysql+pymysql://root:123456@192.168.19.130:3306/test",
                       max_overflow=5,echo=True)
class Host(Base):
    __tablename__ = 'hosts5'
    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)

    # groups = relationship('Group',  #关联group表,这里是类名
    #                   backref = 'host_list') #想要查看一个组包含多少主机,通过host_list调用,单向即可
    #想要看一个主机属于几个组,通过host_list调用
    #把表"group"作为一个对象,通过host_list来调用
    def __repr__(self):
        return  "<id=%s,hostname=%s, ip_addr=%s>" %(self.id,
                                                    self.hostname,
                                                    self.ip_addr)
class Group(Base):
    __tablename__ = 'group5'
    id = Column(Integer,primary_key=True)
    name = Column(String(64),unique=True,nullable=False)
    def __repr__(self):
        return  "<id=%s,name=%s>" %(self.id,self.name)

Base.metadata.create_all(engine) #创建所有表结构 (这句代码至关重要)
if __name__ == '__main__':
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()
    # h1 = Host(hostname='h1',ip_addr="1.23.22.1")
    # h2 = Host(hostname='h2',ip_addr="1.23.22.113")
    # h3 = Host(hostname='h3',ip_addr="1.23.22.12")
    # h4 = Host(hostname='h4',ip_addr="1.23.22.123")
    # session.add_all([h1,h2,h3,h4])  #创建4个主机
    # session.commit()  #提交
    #
    # g3 = Group(name='g3')
    # g4 = Group(name='g4')
    # session.add_all([g3,g4])  #创建2个组
    # session.commit()  #提交

#1内连接(自连接)
    sql=session.query(Host).join(Group,Host.id == Group.id).all() #显示一个表的字段
    # trans_details.query.outerjoin(Uses).filter(Users.username.like('%xx%'))
    print(sql) #[<id=1,hostname=h1, ip_addr=1.23.22.1>, <id=2,hostname=h2, ip_addr=1.23.22.113>]

    sql=session.query(Host,Group).join(Group,Host.id == Group.id).all()  #显示2个表的字段
    # trans_details.query.outerjoin(Uses).filter(Users.username.like('%xx%'))
    print(sql)

#2左连接
    sql=session.query(Host).outerjoin(Group,Host.id == Group.id).all() #显示一个表的字段
    # trans_details.query.outerjoin(Uses).filter(Users.username.like('%xx%'))
    print(sql)
    #[<id=1,hostname=h1, ip_addr=1.23.22.1>, <id=2,hostname=h2, ip_addr=1.23.22.113>,
    # <id=3,hostname=h3, ip_addr=1.23.22.12>, <id=4,hostname=h4, ip_addr=1.23.22.123>]

    sql=session.query(Host,Group).outerjoin(Group,Host.id == Group.id).all()  #显示2个表的字段
    # trans_details.query.outerjoin(Uses).filter(Users.username.like('%xx%'))
    print(sql)



#1自连接(内连接)
# select * from hosts5 INNER JOIN group5 on hosts5.id = group5.id;
#相当于求2个表的交集
# mysql> select * from group5;
# +----+------+
# | id | name |
# +----+------+
# |  1 | g3   |
# |  2 | g4   |
# +----+------+
# 2 rows in set (0.00 sec)
#
# mysql> select * from hosts5;
# +----+----------+-------------+------+
# | id | hostname | ip_addr     | port |
# +----+----------+-------------+------+
# |  1 | h1       | 1.23.22.1   |   22 |
# |  2 | h2       | 1.23.22.113 |   22 |
# |  3 | h3       | 1.23.22.12  |   22 |
# |  4 | h4       | 1.23.22.123 |   22 |
# +----+----------+-------------+------+
# 4 rows in set (0.00 sec)
#
# mysql> select * from host5 INNER JOIN group5 on host5.id = group5.id;
# ERROR 1146 (42S02): Table 'test.host5' doesn't exist
# mysql> select * from hosts5 INNER JOIN group5 on hosts5.id = group5.id;
# +----+----------+-------------+------+----+------+
# | id | hostname | ip_addr     | port | id | name |
# +----+----------+-------------+------+----+------+
# |  1 | h1       | 1.23.22.1   |   22 |  1 | g3   |
# |  2 | h2       | 1.23.22.113 |   22 |  2 | g4   |
# +----+----------+-------------+------+----+------+
# 2 rows in set (0.00 sec)

#2 左连接
# mysql> select * from hosts5 left outer JOIN group5 on hosts5.id = group5.id;
# +----+----------+-------------+------+------+------+
# | id | hostname | ip_addr     | port | id   | name |
# +----+----------+-------------+------+------+------+
# |  1 | h1       | 1.23.22.1   |   22 |    1 | g3   |
# |  2 | h2       | 1.23.22.113 |   22 |    2 | g4   |
# |  3 | h3       | 1.23.22.12  |   22 | NULL | NULL |
# |  4 | h4       | 1.23.22.123 |   22 | NULL | NULL |
# +----+----------+-------------+------+------+------+
# 4 rows in set (0.01 sec)
#

#3 右连接
# mysql> select * from hosts5 right outer JOIN group5 on hosts5.id = group5.id;
# +------+----------+-------------+------+----+------+
# | id   | hostname | ip_addr     | port | id | name |
# +------+----------+-------------+------+----+------+
# |    1 | h1       | 1.23.22.1   |   22 |  1 | g3   |
# |    2 | h2       | 1.23.22.113 |   22 |  2 | g4   |
# +------+----------+-------------+------+----+------+
# 2 rows in set (0.00 sec)

 

posted @ 2016-04-01 11:57  王同佩  阅读(223)  评论(0)    收藏  举报