ORM 与 SQLAlchemy 简介:

ORM 叫对象关系映射,ORM 将对象转换成SQL,然后使用数据API执行SQL并获取执行结果

SQLAlchemy 是Python 社区最知名的 ORM 工具之一,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型。

  1. MySQL-Python
  2. mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
  3.  
  4. pymysql
  5. mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
  6.  
  7. MySQL-Connector
  8. mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
  9.  
  10. cx_Oracle
  11. oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import sqlalchemy
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.ext.declarative import declarative_base
  6. from sqlalchemy import Column, INTEGER, String
  7. from sqlalchemy.orm import sessionmaker
  8. print(sqlalchemy.__version__)
  9.  
  10. engin = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/llt_data',echo=True)#echo=True查看翻译好的sql
  11.  
  12. Base = declarative_base()#生成一个sqlorm基类
  13.  
  14. #定义一个类(类==表,对象==行)
  15. class User(Base):
  16. __tablename__ = 'users'#声明表名
  17. #列值
  18. id = Column(INTEGER,primary_key=True,autoincrement=True)
  19. name = Column(String(10),index=True)
  20. fullname = Column(String(10))
  21. password = Column(String(10))
  22.  
  23. __args__ = (
  24. Index(id, name),#普通索引
  25. uniqueContr(name,fullname)#组合唯一索引
  26. )
  27.  
  28. #可以查看处理的对象具体值
  29. def __repr__(self):
  30. return self.name
  31.  
  32. Base.metadata.create_all(engin)#创建所有表结构
  33. # Base.metadata.drop_all(engine)#删除所有表
  34.  
  35. ed_user = User(name='zc',fullname='zc1',password='')
  36. print(ed_user)
  37. #触发sessionmake类的__call__方法,return得到Session实例,赋给变量session,就可以进行(session.)等等操作
  38. MySession = sessionmaker(bind=engin)
  39. session = MySession()
  40. session.add(ed_user)
  41.  
  42. #插入数据
  43. session.add_all([
  44. User(name='zc1',fullname='zc2',password='123'),
  45. User(name='zc1',fullname='zc2',password='123'),
  46. User(name='zc1',fullname='zc2',password='123'),
  47. User(name='zc1',fullname='zc2',password='123'),
  48. ])
  49.  
  50. session.commit()#每次必须提交
  51.  
  52. print(session.query(User).all())
  53. for row in session.query(User).order_by(User.id):
  54. print(row)
  55.  
  56. for row in session.query(User).filter(User.name.in_(['zc','zc1''zc2'])):#全匹配里面的
  57. print(row)
  58.  
  59. for row in session.query(User).filter(~User.name.in_(['zc4','zc1''zc2'])):#取反,不在这三个之中的数据拿出来
  60. print(row)
  61. print(session.query(User).filter(User.name == 'zc').count())# 拿到数据,计数
  62.  
  63. #and_, or_必须导入
  64. from sqlalchemy import and_, or_
  65.  
  66. for row in session.query(User).filter(and_(User.name == 'zc', User.fullname == 'zc zc2')):#and判断
  67. print(row)
  68.  
  69. for row in session.query(User).filter(or_(User.name == 'zc', User.fullname == 'zc zc2')):#or判断,
  70. print(row)

简单操作表

创建表单:

  1. from sqlalchemy.ext.declarative import declarative_base
  2. from sqlalchemy import Column,Integer,String,ForeignKey,UniqueConstraint,Index
  3. from sqlalchemy.orm import sessionmaker,relationship
  4. from sqlalchemy import create_engine
  5. Base=declarative_base()
  6.  
  7. #定义一个类(类==表,对象==行)
  8. class UserType(Base):
  9. __tablename__='usertype' ##设置表名
  10. id=Column(Integer,primary_key=True,autoincrement=True) ##设置表行
  11. title=Column(String(32),nullable=True,index=True) ##设置表行
  12.  
  13. class Useru(Base):
  14. __tablename__='useru'
  15. id=Column(Integer,primary_key=True,autoincrement=True)
  16. name=Column(String(32),nullable=True,index=True)
  17. email=Column(String(16),unique=True)
  18. user_type_id=Column(Integer,ForeignKey('usertype.id'))
  19. user_type=relationship('UserType',backref='xxoo')
  20. ##设置关联语句 relationship找指定的表名(UserType)创建列名(xxoo)实现双向关联,而在自身的表中创建出一列。
  21.  
  22. engine=create_engine("mysql+pymysql://root:123456:@127.0.0.1:3306/lian?charset=utf8",max_overflow=5)
  23. ##设置连接引擎
  24.  
  25. # 找到所有继承了Base得类,类-SQL语句在数据库创建表
  26. Base.metadata.create_all(engine)
  27.  
  28. # 找到所有继承了Base得类,类-SQL语句在数据库删除表
  29. # Base.metadata.drop_all(engine)

数据行操作:

  1. # 操作数据行:
  2. # # 去引擎中获取一个连接
  3. Session=sessionmaker(bind=engine)
  4. session=Session()
  5. # session.commit()
  6. # session.close()
  7.  
  8. ########表增加#######
  9. # obj=Useru(name='话梅',email='92242@qq.com',user_type_id=2) 要插入每行的内容
  10. # session.add(obj) 通过对象.add(要插入的变量名)进行添加
  11. # session.commit() 通过对象.commit()进行提交
  12. #------单个增加-------
  13.  
  14. #======多个增加=======
  15. # obj=[
  16. # Useru(name='alex1',email='12321@qq.com'),
  17. # Useru(name='alex2',email='12322@qq.com'),
  18. # Useru(name='alex3',email='12323@qq.com'),
  19. # Useru(name='alex4',email='12324@qq.com'),
  20. # Useru(name='alex5',email='12325@qq.com')
  21. #
  22. # ]
  23. #
  24. # session.add_all(obj)
  25. # session.commit()
  26.  
  27. ########查看#########
  28. # user_list=session.query(Useru)
  29. # for row in user_list:
  30. # print(row.name,row.id,row.user_type_id)
  31.  
  32. #要进行表的修改和删除首先要查看表的内容
  33. ########表修改########
  34. # session.query(UserType).filter(UserType.id==1).update({'title':'黄金用户'})
  35. # session.commit()
  36. # session.query(UserType).filter(UserType.id==1).update({UserType.title:UserType.title+"x"},synchronize_session=False)
  37. # session.commit()
  38. # session.query(Useru).filter(Useru.id > 0).update({Useru.name: Useru.name + "x"},synchronize_session=False)
  39. # session.query(Useru).filter(Useru.id>2).update({'num':Users.num+1},synchronize_session='evaluate')
  40. # session.commit()
  41. ########表删除#######
  42. # session.query(UserType).filter(UserType.id==1).delete()
  43. # session.commit()
  44.  
  45. # type_list=session.query(UserType)
  46. # for row in type_list:
  47. # print(row.id,row.title)
  48. # for j in row.xxoo:
  49. # print('-----',j.name)
  1. 其他操作
  2. 条件:
  3. ret=session.query(Useru).filter_by(name='alex').all() #filter_by(键值对方式使用) 可以接收**args类型, .all()
  4.  
  5. ret=session.query(Useru).filter(Useru.id>1,Useru.name=='aelx').all() #filter(条件判断时使用)
  6.  
  7. ret=session.query(Useru).filter(Useru.id.between(1,3),Useru.name=='alex').all()
  8.  
  9. ret=session.query(Useru).filter(Useru.id.in_([1,3,5])).all() #in_就是相当于in
  10.  
  11. ret=session.query(Useru).filter(~Useru.id.in_([1,3,5])).all() #~ 相当于取反的意思
  12.  
  13. ret=session.query(Useru).filter(Useru.id.in_(session.query(Useru.id).filter_by(name='alex'))).all() #多层套嵌条件查询
  14.  
  15. from sqlalchemy import and_,or_
  16.  
  17. ret =session.query(Useru).filter(and_(Useru.id>3,Useru.name=='alex')).all() #and_ 相当于and
  18.  
  19. ret=session.query(Useru).filter(or_(Useru,id<2,Useru.name=='alex')).all() #or_ 相当于or
  20.  
  21. ret=session.query(Useru).filter(or_(Useru.id <2,and_(Useru.name=='alex',Useru.id >3),Useru.extra !='')
  22. )#or_括号里都是or的关系,但是在括号里有一个是and 的关系
  23.  
  24. #通配符:
  25. ret=session.query(Useru).filter(Useru.name.like('e%')).all() #查找name以e开头的
  26. ret=session.query(Useru).filter(~Useru.name.like('e%')).all() #查找name不是以e开头的
  27.  
  28. #限制:
  29. ret=session.query(Useru)[1:2] #通过切片的实现分页的功能
  30.  
  31. #排序:
  32. ret=session.query(Useru).order_by(Useru.name.desc()).all() #以降序进行排序
  33. ret=session.query(Useru).order_by(Useru.name.desc(),Useru.id.asc()).all() #开始以降序进行排序,如果过有重复的就按照id以升序排序
  34.  
  35. #分组:
  36. from sqlalchemy.sql import func
  37. ret =session.query(Useru).group_by(Useru.name).all() #以名字进行分组
  38. ret=session.query(
  39. func.max(Useru.id),
  40. func.sum(Useru.id),
  41. func.min(Useru.id)
  42. ).group_by(Useru.name).all() #以名字进行分组,然后操作合并后的列
  43.  
  44. ret = session.query(
  45. func.max(Useru.id),
  46. func.sum(Useru.id),
  47. func.min(Useru.id)).group_by(Useru.name).having(func.min(Useru.id) >2).all() #有having二次筛选的
  48.  
  49. print(ret)
  50.  
  51. #连表:
  52. ret=session.query(Useru,UserType).filter(UserType.id==Useru.id).all() #进行连表操作
  53. ret =session.query(Useru).join(UserType).all() #这样是inner join (不显示空)
  54. ret = session.query(Useru).join(UserType,isouter=True).all() #这样是left join (显示空)
  55.  
  56. #组合:
  57. q1=session.query(Useru.name).filter(Useru.id >2)
  58. q2=session.query(UserType.id).filter(UserType.id<1)
  59. ret=q1.union(q2).all() #这是去重组合
  60.  
  61. q1 = session.query(Useru.name).filter(Useru.id > 2)
  62. q2 = session.query(UserType.id).filter(UserType.id < 1)
  63. ret = q1.union_all(q2).all() #这是不去
  64.  
  65. #子查询:
  66. q3=session.query(Useru.name).filter(Useru.id >2).subquery()
  67. restt=session.query(q3).all()
  68. print(restt)

创建一对多等:

  1. # 一对多
  2. class Favor(Base):
  3. __tablename__ = 'favor'
  4. nid = Column(Integer, primary_key=True)
  5. caption = Column(String(50), default='red', unique=True)
  6.  
  7. class Person(Base):
  8. __tablename__ = 'person'
  9. nid = Column(Integer, primary_key=True)
  10. name = Column(String(32), index=True, nullable=True)
  11. favor_id = Column(Integer, ForeignKey("favor.nid"))
  12.  
  13. 一对一给外键后面增加唯一:unique=True,
  14.  
  15. # 多对多
  16. class Group(Base):
  17. __tablename__ = 'group'
  18. id = Column(Integer, primary_key=True)
  19. name = Column(String(64), unique=True, nullable=False)# 唯一, 不能为空
  20. port = Column(Integer, default=22)# 端口号=22
  21.  
  22. class Server(Base):
  23. __tablename__ = 'server'
  24.  
  25. id = Column(Integer, primary_key=True, autoincrement=True)
  26. hostname = Column(String(64), unique=True, nullable=False)
  27.  
  28. class ServerToGroup(Base):
  29. __tablename__ = 'servertogroup'
  30. nid = Column(Integer, primary_key=True, autoincrement=True)
  31. server_id = Column(Integer, ForeignKey('server.id'))
  32. group_id = Column(Integer, ForeignKey('group.id'))

ORM原理:

  1. class User
  2. def __init__(self):
  3. self.id=id
  4. self.name=name
  5. self.email=email
  6. def order_by():
  7. pass
  8.  
  9. ogj=User('1.1.1.1','alex','34434@qq.com')
  10. --------------------------------
  11. obj.__dict__={'id':'1.1.1.1','name':'alex','email':'34434@qq.com'}
  12. --------------------------------------------------------------------------
  13. ORM的作用就是把类和对象方式解析成SQL语句(不进行连接,连接借助第三方模块)
  14. code first 通过手动写SQL语句-------->类
  15. db first 通过手动写类--------------->SQL语句
  • ORM解决中文编码问题 sqlalchemy 默认使用latin-1进行编码。所以当出现中文时就会报如下错误:

    1. UnicodeEncodeError: 'latin-1' codec can't encode characters in position 39-41: ordinal not in range(256)
    1. 解决方法:

    在连接数据库的时候直接指定字符编码:

    1. #engine = create_engine("mysql+pymysql://fuzj:123.com@127.0.0.1:3306/fuzj?charset=utf8", max_overflow=5,encoding='utf-8')
  1. ret = session.query(UserType).filter_by(id=1).first()#.first可以取到值
  2. print(ret.name)
  3.  
  4. ret = session.query(UserType).filter_by(id=1).all()#.all取到是个列表内的对象,所以无法取到值
  5. print(ret.name)
  6.  
  7. ret = session.query(Father.name.label('kkk'),Son.name.label('ppp')).join(Son)#.label设置别名
  8. print(ret)

使用__repr__定义返回的数据:

  1. class User(Base):
  2. __tablename__ = 'user'
  3. nid = Column(Integer,primary_key=True,autoincrement=True)
  4. name = Column(String(10),nullable=False)
  5. role = Column(Integer,ForeignKey('role.rid'))
  6. group = relationship("Role",backref='uuu') #Role为类名
  7.  
  8. def __repr__(self):
  9. output = "(%s,%s,%s)" %(self.nid,self.name,self.role)
  10. return output
  11.  
  12. res = session.query(User).all()
  13. print(res)
  14.  
  15. 输出:
  16. [(1,fuzj,1), (2,jie,2), (3,张三,2), (4,李四,1), (5,王五,3)]

ORM 一对多具体使用

mysql表中一对多指的是表A中的数据和表B中的数据存在对应的映射关系,表A中的数据在表B中对应存在多个对应关系,如表A存放用户的角色 DBA,SA,表B中存放用户,表B通过外键关联之表A中,多个用户可以属于同一个角色

  • 设计两张表,user表和role表,

    user 表中存放用户,role表中存放用户角色,role表中角色对应user表中多个用户,user表中一个用户只对应role表中一个角色,中间通过外键约束

    1. from sqlalchemy.ext.declarative import declarative_base
    2. from sqlalchemy import Column, Integer, String,ForeignKey
    3. from sqlalchemy.orm import sessionmaker,relationship
    4. from sqlalchemy import create_engine
    5.  
    6. engine = create_engine("mysql+pymysql://fuzj:123.com@127.0.0.1:3306/fuzj?charset=utf8", max_overflow=5,encoding='utf-8')
    7. Base = declarative_base()
    8.  
    9. class Role(Base):
    10. __tablename__ = 'role'
    11. rid = Column(Integer, primary_key=True, autoincrement=True) #主键,自增
    12. role_name = Column(String(10))
    13.  
    14. def __repr__(self):
    15. output = "(%s,%s)" %(self.rid,self.role_name)
    16. return output
    17.  
    18. class User(Base):
    19. __tablename__ = 'user'
    20. nid = Column(Integer,primary_key=True,autoincrement=True)
    21. name = Column(String(10),nullable=False)
    22. role = Column(Integer,ForeignKey('role.rid')) #外键关联
    23.  
    24. def __repr__(self):
    25. output = "(%s,%s,%s)" %(self.nid,self.name,self.role)
    26. return output
    27. Base.metadata.create_all(engine)
    28.  
    29. Session = sessionmaker(bind=engine)
    30. session = Session()
    31.  
    32. #添加角色数据
    33. session.add(Role(role_name='dba'))
    34. session.add(Role(role_name='sa'))
    35. session.add(Role(role_name='net'))
    36.  
    37. #添加用户数据
    38. session.add_all([
    39. User(name='fuzj',role=''),
    40. User(name='jie',role=''),
    41. User(name='张三',role=''),
    42. User(name='李四',role=''),
    43. User(name='王五',role=''),
    44. ])
    45. session.commit()
    46. session.close()
    1. 普通连表查询:
    2.  
    3. res = session.query(User,Role).join(Role).all() #查询所有用户,及对应的role id
    4. res1 = session.query(User.name,Role.role_name).join(Role).all() #查询所有用户和角色,
    5. res2 = session.query(User.name,Role.role_name).join(Role,isouter=True).filter(Role.role_name=='sa').all() #查询所有DBA的用户
    6. print(res)
    7. print(res1)
    8. print(res2)
    9.  
    10. 输出结果:
    11. [((1,fuzj,1), (1,dba)), ((2,jie,2), (2,sa)), ((3,张三,2), (2,sa)), ((4,李四,1), (1,dba)), ((5,王五,3), (3,net))]
    12. [('fuzj', 'dba'), ('jie', 'sa'), ('张三', 'sa'), ('李四', 'dba'), ('王五', 'net')]
    13. [('jie', 'sa'), ('张三', 'sa')]

    使用relationship 添加影射关系进行查询

    • 首先在User表中添加relationship影射关系

      1. class User(Base):
      2. __tablename__ = 'user'
      3. nid = Column(Integer,primary_key=True,autoincrement=True)
      4. name = Column(String(10),nullable=False)
      5. role = Column(Integer,ForeignKey('role.rid'))
      6. group = relationship("Role",backref='uuu') #Role为类名
      1. 查询:
      2.  
      3. #正向查询
      4. print('正向查询')
      5. res = session.query(User).all() #查询所有的用户和角色
      6. for i in res:
      7. print(i.name,i.group.role_name) #此时的i.group 就是role表对应的关系
      8. res = session.query(User).filter(User.name=='fuzj').first() #查询fuzj用户和角色
      9. print(res.name,res.group.role_name)
      10.  
      11. print('反向查找')
      12. #反向查找
      13. res = session.query(Role).filter(Role.role_name =='dba').first() #查找dba组下的所有用户
      14. print(res.uuu) #此时 print的结果为[(1,fuzj,1), (4,李四,1)]
      15. for i in res.uuu:
      16. print(i.name,res.role_name)
      17.  
      18. 输出结果:
      19. 正向查询
      20. fuzj dba
      21. jie sa
      22. 张三 sa
      23. 李四 dba
      24. 王五 net
      25. fuzj dba
      26. 反向查找
      27. [(1,fuzj,1), (4,李四,1)]
      28. fuzj dba
      29. 李四 dba
        • 说明

          relationship 在user表中创建了新的字段,这个字段只用来存放user表中和role表中的对应关系,在数据库中并不实际存在
          正向查找: 先从user表中查到符合name的用户之后,此时结果中已经存在和role表中的对应关系,group对象即role表,所以直接使用obj.group.role_name就可以取出对应的角色
          反向查找:relationship参数中backref='uuu',会在role表中的每个字段中加入uuu,而uuu对应的就是本字段在user表中对应的所有用户,所以,obj.uuu.name会取出来用户名
          所谓正向和反向查找是对于relationship关系映射所在的表而说,如果通过该表(user表)去查找对应的关系表(role表),就是正向查找,反正通过对应的关系表(role表)去查找该表(user表)即为反向查找。而relationship往往会和ForeignKey共存在一个表中。

      • ORM 多对多具体使用

        Mysql多对多关系指的是两张表A和B本没有任何关系,而是通过第三张表C建立关系,通过关系表C,使得表A在表B中存在多个关联数据,表B在表A中同样存在多个关联数据

        • 创建三张表 host表 hostuser表 host_to_hostuser表

        host表中存放主机,hostuser表中存放主机的用户, host_to_hostuser表中存放主机用户对应的主机,hostuser表中用户对应host表中多个主机,host表中主机对应hostuser表中多个用户,中间关系通过host_to_hostuser表进行关联。host_to_hostuser和host表、user表进行外键约束

        1. from sqlalchemy.ext.declarative import declarative_base
        2. from sqlalchemy import Column, Integer, String,ForeignKey
        3. from sqlalchemy.orm import sessionmaker,relationship
        4. from sqlalchemy import create_engine
        5. class Host(Base):
        6. __tablename__ = 'host'
        7. nid = Column(Integer, primary_key=True,autoincrement=True)
        8. hostname = Column(String(32))
        9. port = Column(String(32))
        10. ip = Column(String(32))
        11.  
        12. class HostUser(Base):
        13. __tablename__ = 'host_user'
        14. nid = Column(Integer, primary_key=True,autoincrement=True)
        15. username = Column(String(32))
        16.  
        17. class HostToHostUser(Base):
        18. __tablename__ = 'host_to_host_user'
        19. nid = Column(Integer, primary_key=True,autoincrement=True)
        20.  
        21. host_id = Column(Integer,ForeignKey('host.nid'))
        22. host_user_id = Column(Integer,ForeignKey('host_user.nid'))
        23.  
        24. Base.metadata.create_all(engine)
        25.  
        26. Session = sessionmaker(bind=engine)
        27. session = Session()
        28.  
        29. #添加数据
        30. session.add_all([
        31. Host(hostname='c1',port='',ip='1.1.1.1'),
        32. Host(hostname='c2',port='',ip='1.1.1.2'),
        33. Host(hostname='c3',port='',ip='1.1.1.3'),
        34. Host(hostname='c4',port='',ip='1.1.1.4'),
        35. Host(hostname='c5',port='',ip='1.1.1.5'),
        36. ])
        37.  
        38. session.add_all([
        39. HostUser(username='root'),
        40. HostUser(username='db'),
        41. HostUser(username='nb'),
        42. HostUser(username='sb'),
        43. ])
        44.  
        45. session.add_all([
        46. HostToHostUser(host_id=1,host_user_id=1),
        47. HostToHostUser(host_id=1,host_user_id=2),
        48. HostToHostUser(host_id=1,host_user_id=3),
        49. HostToHostUser(host_id=2,host_user_id=2),
        50. HostToHostUser(host_id=2,host_user_id=4),
        51. HostToHostUser(host_id=2,host_user_id=3),
        52. ])
        53.  
        54. session.commit()
        55. session.close()
        • 普通多次查询

          1. host_id = session.query(Host.nid).filter(Host.hostname=='c2').first() #查找hostbane对应的hostid,返回结果为元组(2,)
          2. user_id_list = session.query(HostToHostUser.host_user_id).filter(HostToHostUser.host_id==host_id[0]).all() #查询hostid对应的所有userid
          3. user_id_list = zip(*user_id_list) #user_id_list 初始值为[(2,), (4,), (3,)],使用zip转换为[2,4,3]对象
          4. #print(list(user_id_list)) #结果为[(2, 4, 3)]
          5. user_list = session.query(HostUser.username).filter(HostUser.nid.in_(list(user_id_list)[0])).all() #查询符合条件的用户
          6. print(user_list)
          7.  
          8. #或者:
          9. user_id_list = session.query(HostToHostUser.host_user_id).join(Host).filter(Host.hostname=='c2').all()
          10. user_id_list = zip(*user_id_list)
          11. user_list = session.query(HostUser.username).filter(HostUser.nid.in_(list(user_id_list)[0])).all()
          12. print(user_list)
          1. [('db',), ('nb',), ('sb',)]
        • 使用relationship映射关系查询

          • 首先在关系表Host_to_hostuser中加入relationship关系映射

            1. class HostToHostUser(Base):
            2. __tablename__ = 'host_to_host_user'
            3. nid = Column(Integer, primary_key=True,autoincrement=True)
            4.  
            5. host_id = Column(Integer,ForeignKey('host.nid'))
            6. host_user_id = Column(Integer,ForeignKey('host_user.nid'))
            7. host = relationship('Host',backref='h') #对应host表
            8. host_user = relationship('HostUser',backref='u') #对应host_user表
            1. 查询:
            2.  
            3. #查找一个服务器上有哪些用户
            4. res = session.query(Host).filter(Host.hostname=='c2').first() #返回的是符合条件的服务器对象
            5. res2 = res.h #通过relationship反向查找 Host_to_Hostuser中的对应关系
            6. for i in res2: #i为host_to_hostuser表和host表中c2主机有对应关系的条目
            7. print(i.host_user.username) #正向查找, 通过relationship ,找到host_to_hostuser中对应的hostuser 即i.host_user
            8.  
            9. #查找此用户有哪些服务器
            10. res = session.query(HostUser).filter(HostUser.username=='sb').first()
            11. for i in res.u:
            12. print(i.host.hostname)
              • 扩展查询

              不查询关系表,直接在hostuser表中指定关系表,然后获取host表

            在host表中使用 relationship的secondary指定关系表。

            1. class Host(Base):
            2. __tablename__ = 'host'
            3. nid = Column(Integer, primary_key=True,autoincrement=True)
            4. hostname = Column(String(32))
            5. port = Column(String(32))
            6. ip = Column(String(32))
            7. host_user = relationship('HostUser',secondary=lambda :HostToHostUser.__table__,backref='h')
            8.  
            9. 注意使用lambda是为了使表的顺序不在闲置
            10.  
            11. 查询:
            12.  
            13. host_obj = session.query(Host).filter(Host.hostname=='c1').first()
            14. for i in host_obj.host_user:
            15. print(i.username)
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from sqlalchemy.ext.declarative import declarative_base
  4. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  5. from sqlalchemy.orm import sessionmaker, relationship
  6. from sqlalchemy import create_engine
  7.  
  8. engine = create_engine('sqlite:///dbyuan674uu.db', echo=True)
  9.  
  10. Base = declarative_base()
  11.  
  12. class Men_to_Wemon(Base):
  13. __tablename__ = 'men_to_wemon'
  14. nid = Column(Integer, primary_key=True)
  15. men_id = Column(Integer, ForeignKey('men.id'))
  16. women_id = Column(Integer, ForeignKey('women.id'))
  17.  
  18. class Men(Base):
  19. __tablename__ = 'men'
  20. id = Column(Integer, primary_key=True)
  21. name = Column(String(32))
  22. age= Column(String(16))
  23.  
  24. class Women(Base):
  25. __tablename__ ='women'
  26. id = Column(Integer, primary_key=True)
  27. name = Column(String(32))
  28. age= Column(String(16))
  29. bf=relationship("Men",secondary=Men_to_Wemon.__table__,backref='gf')
  30.  
  31. Base.metadata.create_all(engine)
  32.  
  33. Session = sessionmaker(bind=engine)
  34. session = Session()
  35.  
  36. m1=Men(name='alex',age=18)
  37. m2=Men(name='wusir',age=18)
  38. w1=Women(name='如花',age=40)
  39. w2=Women(name='铁锤',age=45)
  40.  
  41. # t1=Men_to_Wemon(men_id=1,women_id=2)
  42.  
  43. m1.gf=[w1,w2]
  44. w1.bf=[m1,m2]
  45.  
  46. session.add_all([m1,m2,w1,w2])
  47.  
  48. session.commit()
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from sqlalchemy.ext.declarative import declarative_base
  4. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  5. from sqlalchemy.orm import sessionmaker, relationship
  6. from sqlalchemy import create_engine
  7.  
  8. engine = create_engine('sqlite:///dbyuan67.db?')
  9.  
  10. Base=declarative_base()
  11.  
  12. class Men(Base):
  13. __tablename__ = 'men'
  14. id = Column(Integer, primary_key=True)
  15. name = Column(String(32))
  16. age= Column(String(16))
  17.  
  18. # __table_args__ = (
  19. # UniqueConstraint('id', 'name', name='uix_id_name'),
  20. # Index('ix_id_name', 'name', 'extra'),
  21. # )
  22.  
  23. def __repr__(self):
  24. return self.name
  25.  
  26. class Women(Base):
  27. __tablename__ ='women'
  28. id = Column(Integer, primary_key=True)
  29. name = Column(String(32))
  30. age= Column(String(16))
  31.  
  32. men_id=Column(String(20), ForeignKey('men.id'))
  33. # def __repr__(self):
  34. # return self.age
  35.  
  36. # Base.metadata.create_all(engine)
  37. # Base.metadata.drop_all(engine)
  38. Session = sessionmaker(bind=engine)
  39. session = Session()
  40. # select * from
  41. # select id,name from women
  42. # sql=session.query(Women).all()
  43. # select * from women inner join men on women.men_id = men.id
  44. sql = session.query(Women.age,Men.name).join(Men).all()
  45. print(sql)
  46. # print(sql)
  47. # r = session.query(session.query(Women.name.label('t1'), Men.name.label('t2')).join(Men).all()).all()
  48. # print(r)
  49.  
  50. # r = session.query(Women).all()
  51. # print(r)
  52.  
  53. # m1=Men(name='alex',age=18)
  54. # w1=Women(name='如花',age=40)
  55. # w2=Women(name='铁锤',age=45)
  56. # m1.gf=[Women(name='如花',age=40),Women(name='铁锤',age=45)]
  57.  
  58. # m1=Men(name='alex',age=18)
  59. # w1=Women(name='如花',age=40,men_id = 1)
  60. # w2=Women(name='铁锤',age=45,men_id = 1)
  61. # session.add_all([w1,w2])
  62. # session.commit()

SQLAlchemy_ORM的更多相关文章

随机推荐

  1. Python3解《剑指》问题:“遇到奇数移至最前,遇到偶数移至最后”

    [本文出自天外归云的博客园] 看到一个<剑指Offer>上的问题:“遇到奇数移至最前,遇到偶数移至最后.” 我做了两种解法.一种是利用python内置函数,移动过程用了插入法,很简单.另一 ...

  2. Qt库版查询

    1 背景 在为嵌入式产品开发Qt应用时,开发所使用的Qt库要和嵌入式系统所支持的Qt库版本一致,否则开发的App无法正确运行.那么,如何查询一个嵌入式系统中所安装Qt库的版本呢?下面将进行一些总结. ...

  3. ORA-00257:archiver error问题处理方法

    原文链接:http://www.7747.net/database/201109/104615.html ORA-00257: archiver error. Connect internal onl ...

  4. Go 实现异常处理机制

    实例: package main import "fmt" type DevideError struct { devidee int devider int } func (de ...

  5. winform利用ImageList控件和ListView控件组合制作图片文件浏览器

    winform利用ImageList控件和ListView控件组合制作图片文件浏览器,见图,比较简单,实现LISTVIEW显示文件夹图片功能. 1.选择文件夹功能代码: folderBrowserDi ...

  6. 正确理解springboot的常用注入方式

    springboot的属性注入 以注入dataSource为例1.springboot默认读取的文件是放在resources目录下的名为application.properties或applicati ...

  7. [OpenCV] Install OpenCV 3.3 with DNN

    OpenCV 3.3 Aug 3, 2017 OpenCV 3.3 has been released with greatly improved Deep Learning module and l ...

  8. Android样式的开发:selector篇

    上一篇详细讲了shape的用法,讲解了怎么用shape自定义矩形.圆形.线形和环形,以及有哪些需要注意的地方.不过,shape只能定义单一的形状,而实际应用中,很多地方比如按钮.Tab.ListIte ...

  9. asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

    通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致 ...

  10. java.util.HashMap的简单介绍

    1. java.util.HashMap的底层实现是数组+链表. 2. 简介put(key, value)方法的执行过程: 1)通过key值,使用散列算法计算出来一个hash值,用来确定该元素需要存储 ...