您的位置:首页 > 编程语言 > Python开发

python学习之路-13

2016-08-06 11:21 459 查看

SQLAlchemy ORM框架

连表操作

一对多

创建表 指定约束 ForeignKey

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)

Base = declarative_base()

# 一对多
class Group(Base):
__tablename__ = "group"
nid = Column(Integer, primary_key=True, autoincrement=True)
caption = Column          # 组名

class User(Base):
__tablename__ = "user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))
group_id = Column(Integer, ForeignKey("group.nid"))  # 外键

Base.metadata.create_all(engine)


插入数据

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)

Base = declarative_base()

# 单表
class Test(Base):
__tablename__ = "test"
nid = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(32))

# 一对多
class Group(Base):
__tablename__ = "group"
nid = Column(Integer, primary_key=True, autoincrement=True)
caption = Column(String(32))          # 组名

class User(Base):
__tablename__ = "user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))
group_id = Column(Integer, ForeignKey("group.nid"))  # 外键

# Base.metadata.create_all(engine)    # 创建表
# Base.metadata.drop_all(engine)    # 删除表

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

### 添加数据
# 向表中添加单条数据
session.add(Group("dba"))
session.add(Group("ddd"))

# 向表中添加多条数据
session.add_all(
[
User(username="a", group_id=1),
User(username="b", group_id=2),
User(username="c", group_id=1)
]
)

session.commit()


查询数据

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)

Base = declarative_base()

### 创建表结构
# 单表
class Test(Base):
__tablename__ = "test"
nid = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(32))

# 一对多
class Group(Base):
__tablename__ = "group"
nid = Column(Integer, primary_key=True, autoincrement=True)
caption = Column(String(32))          # 组名

class User(Base):
__tablename__ = "user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))
group_id = Column(Integer, ForeignKey("group.nid"))  # 外键

# 与生成表结构无关,仅用于更方便的进行连表查询
group = relationship("Group", backref="user")

def __repr__(self):
temp = "%s - %s - %s" % (self.nid, self.username, self.group_id)
return temp

# Base.metadata.create_all(engine)    # 创建表
# Base.metadata.drop_all(engine)    # 删除表

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

"""
### 添加数据
# 向表中添加单条数据
session.add(Group("dba"))
session.add(Group("ddd"))

# 向表中添加多条数据
session.add_all(
[
User(username="a", group_id=1),
User(username="b", group_id=2),
User(username="c", group_id=1)
]
)

session.commit()
"""

# # 查询单表中所有数据
# ret = session.query(User).all()
# print(ret)  # 输出User类中__repr__方法中返回的字符串
# for obj in ret:
#     print(obj.nid, obj.username, obj.group_id)
#
# # 通过指定列查询
# ret = session.query(User.nid, User.username).all()
# print(ret)  # 返回一个列表,列表中包含每一行的数据  [(2, 'a'), (3, 'b'), (4, 'c')]

# # 根据指定条件查询
# ret = session.query(User).filter(User.username == "a").all()
# obj = ret[0]
# print(obj.nid, obj.username, obj.group_id)

# 连表查询

# 通过join进行连表查询
# ret = session.query(User).join(Group)   # 返回执行的sql语句
# print(ret)
# print("------")
# ret = session.query(User).join(Group).all()
# for obj in ret:
#     print(obj.nid, obj.username, obj.group_id)
#
# ret = session.query(User, Group).join(Group).all()
# print(ret)
#
#
# ret = session.query(User.username, Group.caption).join(Group).all()
# print(ret)

# 通过relationship在创建表的类中指定连表的对应关系,然后进行连表查询
# 正向查询  (正向查找不能够过滤组的字段)
ret = session.query(User).all()
for obj in ret:
# obj代指user表中的每一行数据
# obj.group代指obj当前对应的group表中数据的对象
print(obj.nid, obj.username, obj.group_id, obj.group, obj.group.nid, obj.group.caption)

# 反向查询
# 查找所有组名为dba的用户信息
obj = session.query(Group).filter(Group.caption=="dba").first()
print(obj.nid, obj.caption, obj.user)    # obj.user 这个地方的user是在User类中使用relationship创建对应关系中 backref对应的值


多对多

原始方法和新式方法1

### 关系在第三张表中

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", 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(32))
ip = Column(String(32))

class HostUser(Base):
"""
登录主机的用户表
"""
__tablename__ = "host_user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))

class Host_HostUser(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("host_user.nid"))

host = relationship("Host", backref="h")
host_user = relationship("HostUser", backref="u")

# Base.metadata.create_all(engine)    # 创建表

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

# # 向host主机表中添加多条数据
# 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_user登录主机用户表中添加多条数据
# session.add_all(
#     [
#         HostUser(username="root"),
#         HostUser(username="aa"),
#         HostUser(username="bb"),
#         HostUser(username="cc"),
#     ]
# )

# # 向host_to_host_user关系表中添加多条数据
# session.add_all(
#     [
#         Host_HostUser(host_id=1, host_user_id=1),
#         Host_HostUser(host_id=1, host_user_id=2),
#         Host_HostUser(host_id=1, host_user_id=3),
#         Host_HostUser(host_id=1, host_user_id=4),
#         Host_HostUser(host_id=2, host_user_id=2),
#         Host_HostUser(host_id=2, host_user_id=4),
#         Host_HostUser(host_id=3, host_user_id=1),
#         Host_HostUser(host_id=3, host_user_id=3),
#     ]
# )

# session.commit()

# 需求:找出能够登录主机名为c1的所有用户
# ### 原始方式
# # 从host表中将找到主机名为c1的nid
# host_obj = session.query(Host).filter(Host.hostname == "c1").first()
#
# # 通过主机名为c1的nid在关系表中找到用户的id
# host_2_host_user = session.query(Host_HostUser.host_user_id).filter(Host_HostUser.host_id==host_obj.nid).all()
#
# r = zip(*host_2_host_user)
# users = session.query(HostUser.username).filter(HostUser.nid.in_(list(r)[0])).all()
# print(users)

### 原始方式结合
ret = session.query(HostUser.username).filter(HostUser.nid.in_(session.query(Host_HostUser.host_user_id).filter(Host_HostUser.host_id == session.query(Host.nid).filter(Host.hostname == 'c1')))).all()
print(ret)

### 新式方法
# 通过在Host_HostUser类中使用relationship建立与Host类和HostUser类建立关系,然后使用反向查询和正向询进行查找
host_obj = session.query(Host).filter(Host.hostname=="c1").first()
for item in host_obj.h:   # host_obj.h 反向查询
print(item.host_user.username)  # item.host_user.username  正向查询


新式方法2

### 关系在第1张表中 secondary=Host_HostUser.__table__ 要将关系表放在最上面 如果不使用lambda则应该将关系表放在最上面

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)

Base = declarative_base()

class Host_HostUser(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("host_user.nid"))

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=Host_HostUser.__table__,
backref="h")

class HostUser(Base):
"""
登录主机的用户表
"""
__tablename__ = "host_user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))

# Base.metadata.create_all(engine)    # 创建表

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

# # 向host主机表中添加多条数据
# 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_user登录主机用户表中添加多条数据
# session.add_all(
#     [
#         HostUser(username="root"),
#         HostUser(username="aa"),
#         HostUser(username="bb"),
#         HostUser(username="cc"),
#     ]
# )

# # 向host_to_host_user关系表中添加多条数据
# session.add_all(
#     [
#         Host_HostUser(host_id=1, host_user_id=1),
#         Host_HostUser(host_id=1, host_user_id=2),
#         Host_HostUser(host_id=1, host_user_id=3),
#         Host_HostUser(host_id=1, host_user_id=4),
#         Host_HostUser(host_id=2, host_user_id=2),
#         Host_HostUser(host_id=2, host_user_id=4),
#         Host_HostUser(host_id=3, host_user_id=1),
#         Host_HostUser(host_id=3, host_user_id=3),
#     ]
# )

# session.commit()

# 需求:找出能够登录主机名为c1的所有用户
### 新式方法二

host_obj = session.query(Host).filter(Host.hostname=="c1").first()
print(host_obj.host_user)


新式方法三

### secondary="host_to_host_user" 关系表无顺序要求 如果不使用lambda则应该将关系表放在最上面

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", 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(32))
ip = Column(String(32))

host_user = relationship("HostUser",
secondary="host_to_host_user",
backref="h")

class HostUser(Base):
"""
登录主机的用户表
"""
__tablename__ = "host_user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))

class Host_HostUser(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("host_user.nid"))

# Base.metadata.create_all(engine)    # 创建表

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

### 新式方法三

host_obj = session.query(Host).filter(Host.hostname=="c1").first()
print(host_obj.host_user)


新式方法四

### secondary=lambda : Host_HostUser.__table__  如果不使用lambda则应该将关系表放在最上面

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", 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(32))
ip = Column(String(32))

host_user = relationship("HostUser",
secondary=lambda : Host_HostUser.__table__,
backref="h")

class HostUser(Base):
"""
登录主机的用户表
"""
__tablename__ = "host_user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))

class Host_HostUser(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("host_user.nid"))

# Base.metadata.create_all(engine)    # 创建表

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

### 新式方法四

host_obj = session.query(Host).filter(Host.hostname=="c1").first()
print(host_obj.host_user)


新式方法五

### 关系表需要使用Table()进行创建
### relationship 中secondary=Host_HostUser, 如果不使用lambda则应该将关系表放在最上面

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://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)

Base = declarative_base()

Host_HostUser = Table('host_to_host_user', Base.metadata,
Column('nid', Integer, primary_key=True, autoincrement=True),
Column('host_id', Integer, ForeignKey("host.nid")),
Column('host_user_id', Integer, ForeignKey("host_user.nid")),
)

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=Host_HostUser,
backref="h")

class HostUser(Base):
"""
登录主机的用户表
"""
__tablename__ = "host_user"
nid = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(32))

# Base.metadata.create_all(engine)    # 创建表

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

### 新式方法五

host_obj = session.query(Host).filter(Host.hostname=="c1").first()
print(host_obj.host_user)


paramiko模块

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: