python 之 sqlalchemy练习

sqlalchemy

single_table(单表)

#!/bin/bin/env python
# -*-coding:utf-8 -*-
# Author : rain

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



engine = create_engine("mysql+pymysql://root:123.com@10.10.36.101/s13", max_overflow=5)
Base = declarative_base()

# 单表
class Single_table(Base):
    __tablename__ = 'single_table'
    id = Column(Integer, primary_key='True', autoincrement='True')
    name = Column(String(24))
    extra = Column(String(16))

    __table_args__ = (
    UniqueConstraint('id', 'name', name='uix_id_name'),
        Index('ix_id_name', 'name', 'extra'),
    )

def init_db():
    Base.metadata.create_all(engine)

def drop_db():
    Base.metadata.drop_all(engine)

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

# 添加一条数据
obj = Single_table(name='rain', extra='set')
# obj = Single_table(name='wind', extra='put')
session.add(obj)
session.commit()

# 查询Single_table中id,name,extra的第一条记录
obj = session.query(Single_table).filter(Single_table.id == 1).first()
print(obj.id, obj.name, obj.extra)   # 1 rain set

# 查询Single_table中id,name,extra的所有记录
obj = session.query(Single_table.id, Single_table.name, Single_table.extra).all()
print(obj)   # [(1, 'rain', 'set')]

# 查询Single_table表中name为rain的所有记录
obj = session.query(Single_table).filter_by(name='rain').all()
print(obj)          # [<__main__.Single_table object at 0x0000000003ADB390>]

# 查询Single_table表中name为rain的第一条记录
ret = session.query(Single_table).filter_by(name='rain').first()
print(ret)          # <__main__.Single_table object at 0x0000000003ADB390>

# 查询Single_table中id为1,name为rain的记录
ret = session.query(Single_table).filter(Single_table.id == 1, Single_table.name == 'rain').all()

# 查询Single_table中id在[1, 3]之间,name为rain的记录
ret = session.query(Single_table).filter(Single_table.id.between(1, 3), Single_table.name == 'rain').all()

# in_
ret = session.query(Single_table).filter(Single_table.id.in_([1, 3, 4])).all()
# print(ret)
# 非in_
ret = session.query(Single_table).filter(~Single_table.id.in_([1, 3, 4])).all()

ret = session.query(Single_table).filter(Single_table.id.in_(session.query(Single_table.id).filter_by(name='rain'))).all()
print(ret[0].id, ret[0].name, ret[0].extra)     
# 1 rain set

ret = session.query(Single_table).filter(
    or_(
        Single_table.id < 2,
        and_(Single_table.name == 'rain', Single_table.id > 3),
        Single_table.extra != ""
    )).all()

print(ret[0].id, ret[1].id, ret[2].id)


ret = session.query(Single_table).filter(Single_table.name.like('ra%')).all()
print(ret[0].name, ret[1].name)      # rain ray

# 通配符
ret = session.query(Single_table).filter(~Single_table.name.like('ra%')).all()
print(ret[0].name)         
# wind

# 限制,只打印第二个
ret = session.query(Single_table)[1:2]
print(ret)

# 排序,按名字排序
ret = session.query(Single_table).order_by(Single_table.name.desc()).all()
print(ret[0].id, ret[1].id, ret[2].id)          
# 3 2 1

ret = session.query(Single_table).order_by(Single_table.name.desc(), Single_table.id.asc()).all()
print(ret[0].id, ret[1].id, ret[2].id)

# 分组
from sqlalchemy.sql import func
ret = session.query(Single_table).group_by(Single_table.extra).all()

ret = session.query(
    func.max(Single_table.id),
    func.sum(Single_table.id),
    func.min(Single_table.id),
).group_by(Single_table.name).all()
print(ret)    # [(1, Decimal('1'), 1), (2, Decimal('2'), 2), (3, Decimal('3'), 3)]

ret = session.query(
    func.max(Single_table.id),
    func.sum(Single_table.id),
    func.min(Single_table.id),
).group_by(Single_table.name).having(func.min(Single_table.id) > 2).all()
print(ret)    # [(3, Decimal('3'), 3)]

More than a pair of一对多

#!/bin/bin/env python
# -*-coding:utf-8 -*-
# Author : rain

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

engine = create_engine("mysql+pymysql://root:123.com@10.10.36.101/s13", max_overflow=5)
Base = declarative_base()

# 一对多
class Groups(Base): __tablename__ = 'groups' nid = Column(Integer, primary_key='True', autoincrement='True') caption = Column(String(24), unique=True) class Users(Base): __tablename__ = 'users' nid = Column(Integer, primary_key='True', autoincrement='True') name = Column(String(24), nullable='True') group_id = Column(Integer, ForeignKey("groups.nid")) # 正向查找 ,反向查找 group = relationship('Groups', backref='user') def init_db(): Base.metadata.create_all(engine) def drop_db(): Base.metadata.drop_all(engine) Session = sessionmaker(bind=engine) session = Session() # session.add_all(/ session.add_all([ Users(name='tom', group_id=2), Users(name='rain', group_id=2), Users(name='jerry', group_id=2), Users(name='eric', group_id=1), ]) session.commit() # 输出原生sql sql = session.query(Users.name, Groups.caption).join(Groups, isouter=True).filter(Users.name=='rain') print(sql) # SELECT users.name AS users_name, groups.caption AS groups_caption # FROM users LEFT OUTER JOIN groups ON groups.nid = users.group_id # WHERE users.name = :name_1 # 查询rain属于哪个组 ret = session.query(Users.name, Groups.caption).join(Groups, isouter=True).filter(Users.name == 'rain').all() print(ret) # [('rain', 'A_group'), ('rain', 'B_group')] # 输出原生sql sql = session.query(Users.name, Groups.caption).join(Groups, isouter=True) print(sql) # SELECT users.name AS users_name, groups.caption AS groups_caption # FROM users LEFT OUTER JOIN groups ON groups.nid = users.group_id # 查询所有用户分别属于哪个组 ret = session.query(Users.name, Groups.caption).join(Groups, isouter=True).all() print(ret) # [('rain', 'A_group'), ('tom', 'B_group'), ('rain', 'B_group'), ('jerry', 'B_group'), ('eric', 'A_group')] # 输出原生sql sql = session.query(Users.name, Groups.caption).join(Groups, isouter=True).filter(Groups.caption == 'B_group') print(sql) # SELECT users.name AS users_name, groups.caption AS groups_caption # FROM users LEFT OUTER JOIN groups ON groups.nid = users.group_id # WHERE groups.caption = :caption_1 # 查看B_group中有哪些用户 ret = session.query(Users.name, Groups.caption).join(Groups, isouter=True).filter(Groups.caption == 'B_group').all() print(ret) # [('tom', 'B_group'), ('rain', 'B_group'), ('jerry', 'B_group')] # 正向查询 (group = relationship("Group", backref='user'),通过这一句建立关系,然后可以通过这种关系查询更方便) # 查询rain用户属于哪个组 ret = session.query(Users).filter(Users.name == 'rain').first() print(ret.name, ret.group.caption) # rain A_group # 查询所有用户分别属于哪个组 ret = session.query(Users).all() for obj in ret: # obj代指user表的每一行数据 # obj.group代指group对象, print(obj.name, obj.group.caption) # 反向查询 # 查询A_group组有哪些人 obj = session.query(Groups).filter(Groups.caption == 'A_group').first() # obj 指代groups表里组名为A_group的那一行数据 # obj.user 指代users对象(组为A_group的用户数据) for item in obj.user: print(item.name, end=' ')

 

many_to_many(多对多)
#!/bin/bin/env python
# -*-coding:utf-8 -*-
# Author : rain

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

engine = create_engine("mysql+pymysql://root:123.com@10.10.36.101/s13", max_overflow=5)

Base = declarative_base()

class Host(Base):
    __tablename__ = 'host'
    nid = Column(Integer, primary_key='True', autoincrement='True')
    hostname = Column(String(32))
    port = Column(String(12))
    ip = Column(String(32))
    host_user = relationship('HostUser', secondary=lambda: HostToHostUser.__table__, backref='host')


class HostUser(Base):
    __tablename__ = 'hostuser'
    nid = Column(Integer, primary_key='True', autoincrement='True')
    username = Column(String(32))

# 多对多(需要第三张表,专门用来存关系,一个用户可以登录多个服务器,一个服务器上可以有多个用户)
class HostToHostUser(Base):
    __tablename__ = 'host_to_host_user'
    nid = Column(Integer, primary_key='True', autoincrement='True')
    host_id = Column(Integer, ForeignKey('host.nid'))
    host_user_id = Column(Integer, ForeignKey('hostuser.nid'))

def init_db():
    Base.metadata.create_all(engine)

def drop_db():
    Base.metadata.drop_all(engine)

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

session.add_all([
    Host(hostname='web1', port='22', ip='192.168.1.65'),
    Host(hostname='web2', port='22', ip='192.168.1.66'),
    Host(hostname='web3', port='22', ip='192.168.1.67'),
    Host(hostname='web4', port='22', ip='192.168.1.68'),
    Host(hostname='web5', port='22', ip='192.168.1.69'),
])
session.commit()

session.add_all([
    HostUser(username='root'),
    HostUser(username='tom'),
    HostUser(username='jerry'),
    HostUser(username='jack'),
    HostUser(username='rose'),
])
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()

# 需求:获取web1服务器中的所有用户

# 原始方式需要经过三步:
# 第一步:查询web1的服务器ID
host_obj = session.query(Host.nid).filter(Host.hostname == 'web1').first()
print(host_obj)
# 第二步:查询第三张表(关系表)查询所有用户的ID  host_id == host_obj.nid
ret1 = session.query(HostToHostUser.host_user_id).filter(HostToHostUser.host_id == host_obj.nid).all()
print(ret1)
uid = list(zip(*ret1))[0]
# 第三步:根据用户ID查找所有用户
# users = session.query(HostUser.username).filter(HostUser.nid.in_(uid)).all()
# users = [x[0] for x in users]
# print(users)

# 正向查询
# host_user = relationship('HostUser', secondary=lambda: HostToHostUser.__table__, backref='host')
# 上面这个话的意思是说给通过第三张表HostToHostUser给HostUser表建立关系
ret = session.query(Host).filter(Host.hostname == 'web1').first()
for item in ret.host_user:
    print(item.username, end=' ')

# 需求2:获取tom用户可以登录哪些服务器

# 原始方式需要经过三步
# 第一步:查询tom用户的id
user_id = session.query(HostUser.nid).filter(HostUser.username == 'tom').first()
print(user_id)

# 第二步:查询第三张表(关系表),查询所有服务器的ID, 条件是 user_obj.nid == host_user_id
group_user_id = session.query(HostToHostUser.host_id).filter(HostToHostUser.host_user_id == user_id.nid).all()
print(group_user_id)
g_u_id = list(zip(*group_user_id))[0]

# 根据服务器ID查找服务器hostname
host_list = session.query(Host).filter(Host.nid.in_(g_u_id)).all()
host = [x.hostname for x in host_list]
print(host)

# 反向查询
host_user = relationship('HostUser', secondary=lambda: HostToHostUser.__table__, backref='host')
host_user_obj = session.query(HostUser).filter(HostUser.username == 'tom').first()
for item in host_user_obj.host:
    print(item.hostname)
posted @ 2016-08-03 15:11  yxy_linux  阅读(385)  评论(0编辑  收藏  举报