SQLAlchemy

a 夏天 提交于 2020-02-08 01:41:58

以上,SQLAlchemy的两个最重要的前端部分是ORM(Object Relational Mapper,,即对象关系映射器)和 SQL表达式语言。SQL表达式可以独立于ORM使用。使用ORM时,SQL表达式语言仍然是面向对象的API的一部分,因为它在对象关系配置和查询中使用。

SQLAlchemy是python中的ORM框架。对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping)其他语言中都会有ORM框架,可以进行更加快捷便利的操作数据库。
SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

注意:SQLAlchemy本身无法操作数据库,必须依赖第三方插件如pymysql,mysqlDB,Dialect用于和数据API进行交流,根据配置文件的不同调用不同数据库的API,从而实现对数据库的操作。

 

一,创建表

默认的情况下SQLAlchemy不能修改表结构,可以下载第三方工具进行修改。

#!/usr/bin/python
# _*_ coding:utf-8 _*_
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@10.1.1.3:3306/s13", max_overflow=5)
# 创建连接

Base = declarative_base() # 规定的必须要写这一步

# ------------------创建单表-----------------------
class Users(Base):  #必须继承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'),
	)


# -----------------一对多-----------------------
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)
	port = Column(Integer, default=22)


class Server(Base):
	__tablename__ = 'server'

	id = Column(Integer, primary_key=True, autoincrement=True)
	hostname = Column(String(64), unique=True, nullable=False)


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)  # 找到Base所有的子类,根据类去创建表


def drop_db():
	Base.metadata.drop_all(engine)
# init_db()   # 创建所有的表
drop_db() # 删除所有的表

  

 

 二,操作表

#!/usr/bin/env python
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@10.1.1.3:3306/s13", 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):    # 这个方法是SQLAlchemy内部自己规定的,这个函数对查询没有一点用处,只是在打印对象时方便查看
		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')


# 多对多
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()


# ------增--------
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()
session.commit()


# -------改---------
session.query(Users).filter(Users.id > 2).update({"name": "099"})
session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + "099"}, synchronize_session=False)
# 字符串的相加
session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate")
# 数字的相加,synchronize_session="evaluate",这样设置之后就会把值当成数字进行相加。
session.commit()


# --------查-----------
ret = session.query(Users).all()  # 查询所有,此时返回的是User对象列表
ret = session.query(Users.name, Users.extra).all()  # 查询两列
ret = session.query(Users).filter_by(name='alex').all()  # 过滤出name='alex'的所有
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]   # 相当于mysql中的limit

# 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()  # 按照name排序,name相同再按照id排序


# 分组
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,自动连表(在内部会找foreignkey)
ret = session.query(Person).join(Favor, isouter=True).all()  # isouter=True表示的是left  join


# 组合
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()  # 默认不去重 

  

三,详解一对多

 


group

nid caption
1 1
2 2

 

user 

nid username goup_id
1 lintao 1
2 lily 1
3 lucy 1

 

创建上述表并对表进行简单的操作

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
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@10.1.1.3:3306/s13", max_overflow=5)

Base = declarative_base()  # 固定用法


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'))  #(引擎必须是InnoDB)创建外键,对两张表进行关联
	
# 注意mysql的引擎从5.5.5开始默认引擎是InnoDB, 之前的版本默认是MyISAM引擎,MyISAM不支持外键,此时需要
# 修改配置文件/etc/my.cnf  在mysqld下面增加一行:default-storage-engine=INNODB,然后重启即可生效。


Base.metadata.create_all(engine)   # 创建表
Base.metadata.drop_all(engine)
Session = sessionmaker(bind=engine)  # 相当于保持一个会话
session = Session()

# 创建group表记录
session.add(Group(caption='dba'))  # 记录逐条添加
session.add(Group(caption='dbd'))
session.commit()   #必须提交,否则不会生效

# 创建user表记录
session.add_all([   # 一次性添加多条记录
	User(username='lin', group_id=1),
	User(username='lily', group_id=2),
	User(username='lucy', group_id=3)   # 此时如果group表中的nid没有为3的,那么此时这条记录就会报错!这就是外键的作用
])
session.commit()


# 对表进行操作
	sql = session.query(User).filter(User.username == "tom")  # 返回的是SQL语句
	print(sql)

	ret = session.query(User).filter(User.username == "tom").all()  # 返回的是一个对象的列表
	# 如果返回的对象不知道是什么的话,可以在SQLAlchemy可以用repr方法进行自定制
	print(ret)

	ret1 = session.query(User.username).filter(User.username == "tom").all()  # 返回的是username这一列,中的'tom'
	print(ret1)

# 连表查询,这里不用像SQL语句中还要加on字段,这里由SQLAlchemy会在内部自动查找foreignkey
	sql_1 = session.query(User).join(Group)
	sql_2 = session.query(User).join(Group, isouter=True)
	ret2 = session.query(User).join(Group).all()
	print(sql_1)  # 通过sql语句可以看出默认的是inner join
	print(sql_2)  # 通过添加isouter = True, 可以更改为left join
	print(ret2)  # 进行关联查询所有的数据

  

小结:
1,创建表需要指定外键
2,类, repr方法(# 这个方法是SQLAlchemy内部自己规定的,这个函数对查询没有一点用处,只是在打印对象时方便查看)
3,单表
4,连表 session.query("表一").join("表二").all()

 

上面我们发现查询在查询的时候只有user表,能不能查到group表呢?

ret3 = session.query(User, Group).all()  # 返回的是对象
ret4 = session.query(User.username, User.nid, Group.caption, Group.nid).all()  #返回的是列
print(ret3)
print(ret4)

  

下面针对上述表我们提出一个需要:如何获取caption为‘dba’所有的用户名?

 

第一种实现方式

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
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@10.1.1.3:3306/s13", max_overflow=5)
Base = declarative_base()


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='pers')  # 与表结构无关,仅用来查询
    # relationship("类名")

    def __repr__(self):  # 这里只是来用打印对象时有用,对于查询无用
        tmp = "%s -- %s :%s" % (self.nid, self.username, self.group_id)
        return tmp

Session = sessionmaker(bind=engine)  # 相当于保持一个会话
session = Session()
join连表的方式

 

第二种实现方式

其中第二种实现方式,有分为两种,我们姑且称之为:正向查找和反向查找

由于连表操作比较麻烦,SQLAlchemy又提供了一个新的功能。在声明外键(ForeignKey)的表中增加一个新的字段,group = relationship("Group", backref='pers'),一般情况下foreikey和relationship在一张表里面。这一功能和Django中的类似。到底这个字段代表什么含义呢?

 

1,group字段含义是什么?(正向查找,通过带有关系(relationship)的表向其他地方找)

#通过user表来查询
ret = session.query(User).all()
for obj in ret:
    # obj 代指user表中的每一行数据
    # obj.group 代表的是由Group实例化的对象(对象封装的东西和user相关)
    print(obj.username, obj.group_id, obj.nid)
    print(obj.group, obj.group.nid, obj.group.caption)  # SQLAlchemy在内部做的关联
    print("----------------")
正向查找

 

2,backref=pers字段是什么含义?(反向查找,通过其他表,来找到带有relation的表)

# 通过group表来查询
obj = session.query(Group).filter(Group.caption == 'dba').first()
print(obj.nid)
print(obj.caption)

print(obj.pers)   
#注意这里是反向查找,此时的obj.pers代表的是User实例化对象(对象封装的内容和group相关),和正向恰好相反,结合
正向查找去理解
反向查找

 

注意pers在数据库中并没有真实的表与其对应,只是SQLAlchemy在内存中生成的SQL语句而已。就相当于在group表中增加了一个pear字段,就像表user中的group字段一样。

 

 

四,表创建过程


  1,先把写好的类转换为table对象,
  2,然后根据table对象生成SQL语句

注意:在python中并没有严格的限制,可以直接用table对象生成SQL语句,一般正式和标准的用法都会用类来生成。在其他语言中只允许用类生成表。

 

 

五,详解多对多

server

server_id server_name port ip
1 c1 xx xxx.xx.xx.x
2 c2 xx xx.xx.xx.xx
3 c3 xxxx xx.xxx.xx.x

server_user

user_id user_name
1 tom
2 lily
3 lucy

 

一台主机可以有多个用户,一个用户又可以同时存在多个主机,这就是多对多的关系,这时需要建立第三张关系表

relation_table

sid uid
1 1
1 3
2 2
3 2
3 1

此时还需要对第三张表建立约束:外键,这样可以控制数据的一致性和完整性

 

 创建表结构并插入数据

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
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@10.1.1.3:3306/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(32))
	ip = Column(String(32))


class HostUser(Base):
	__tablename__ = 'host_user'
	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('host_user.nid'))

# 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(hostname='c4', port='22', ip='1.1.1.4'),
	Host(hostname='c5', port='22', ip='1.1.1.5'),
])
session.commit()

# 添加host_user表中数据
session.add_all([
	HostUser(username='root'),
	HostUser(username='db'),
	HostUser(username='nb'),
	HostUser(username='sb'),
])
session.commit()

# 添加host_to_host_user表中数据
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()

  

需求:如何获取主机1中所有的用户?

 

方案一:传统方式

思路:
1,先通过主机1的主机名在host表,获取主机的nid
2,在通过主机的nid,在host_to_host_user表中找到对应的host_user_id,为用户的ID
3,最后在host_user表中找到和用户id相对应的用户的信息

host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
# print(host_obj.nid)
# 1

host_2_host_user = session.query(HostToHostUser.host_user_id).filter(HostToHostUser.host_id == host_obj.nid).all()
# print(host_2_host_user)
# [(1,), (2,), (3,)]
# 如何把它转换为列表,或者元组,
# >>> li
# [('a',), ('b',), ('c',)]
# >>> r = map(lambda x:x[0], li)
# >>> print(list(r))
# ['a', 'b', 'c']
# 也可以用r = zip(*host_2_host_user)--> list(r[0])此时为元组('a', 'b', 'c')

users = session.query(HostUser.username).filter(HostUser.nid.in_(map(lambda x: x[0], host_2_host_user))).all()
print(users)
# 注意这里fliter不但支持==,还支持in的操作

执行结果:
[('root',), ('db',), ('nb',)]
View Code

 

方案二:新方式(常用)

 

A

AB ==> foreign_key relationship

B

 

!/usr/bin/env python
# _*_ coding:utf-8 _*_
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@10.1.1.3:3306/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(32))
    ip = Column(String(32))


class HostUser(Base):
    __tablename__ = 'host_user'
    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('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_obj = session.query(Host).filter(Host.hostname == 'c1').first()
print(host_obj.nid, host_obj.hostname, host_obj.port)
print(host_obj.h)  # 此时的h代表的HostToHostUsers实例化的对象(和Host相关的)

# 循环获取第三张表对应的对象
for item in host_obj.h:
    # print(item.host_user) # 获取HostUser实例化的和关系表相关的内容
    r = item.host_user.username
    print(r)
 思路:先通过反向查找,找到HostToHostUser(即关系表)实例化的对象,然后再通过这个对象获取host_user这个字段,这个字段即代表HostUser(即关系表)对象,此时正向查找到相对应的host表中的uername
View Code

 

方案三:新方式(不常用,不太合理)    对象+类的方法创建的

A ==> relationship

AB ==> foreign_key

B

这里的关系表和foreign_key没有放在一张表里面

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index, Table  #这里需要导入Table模块
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

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


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


HostToHostUser = Table('host_to_host_user', Base.metadata,
                       Column('host_id', ForeignKey('host.nid'), primary_key=True),
                       Column('host_user_id', ForeignKey('host_user.nid'), primary_key=True),
                       )


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, backref='h')
     # 注意这里的secondary为关系表的名字:HostToHostUser

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

host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
# print(list(map(lambda x: x.username, host_obj.host_user)))
for item in host_obj.host_user:
    print(item.username)
View Code

 

方案四:也比较合理,简单

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index, Table
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://root:123@10.1.1.3:3306/s13", max_overflow=5)
Base = declarative_base()


class HostUser(Base):
    __tablename__ = 'host_user'
    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('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=HostToHostUser.__table__, backref='h')
    # 注意这里的secondary为:HostToHostUser, __table__为获取的table对象

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

host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
# print(list(map(lambda x: x.username, host_obj.host_user)))
for item in host_obj.host_user:
    print(item.username)
View Code

 

SQLAlchemy总结:


1,orm自动生成表,然后根据类和对象去生成表
2,创建表,简单
3,操作表(其实就是转换SQL语句),需要多练。
  单表
  连表
    right.join, left join, inner join
    关系:
      一对多(一般情况下外键和关系会放到一起,foreignkey,relationship)
      多对多
        多一张表,放的是foreignkey,关联约束
        1,关系表:放关系
        2,A:放关系 ,(B, AB)

练习的顺序:从上往下练习,能用SQL就用SQL,像涉及到一对多和多对多时,SQLAlchemy比较简单的再考虑用。

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!