1.SQLAlchemy之一对多关系

1.1 创建单表

  1. class Test(Base):
  2. __tablename__ = 'user'
  3. nid = Colume(Integer,primary_key=True,autoincrement=True)
  4. name = Colume(String(32))

1.2 创建一对多

  1. class Team(Base):
  2. __tablename__ = 'team'
  3. tid = Colume(Integer,primary_key=True,autoincrement=True)
  4. caption = Colume(String(32))
  5.  
  6. class user(Base):
  7. __tablename__ = 'user'
  8. nid = Colume(Integer,primary_key=True,autoincrement=True)
  9. name = Colume(String(32))
  10. team_id = Colume(Integer,ForeignKey('team.gid'))

写完类,接下来就是把类转化为数据库表了。

1.3 生成表、删除表

  1. def init_db():
  2. #根据Base去找它的子类,把所有的子类生成表。
  3. Base.metadata.create_all(engine)
  4.  
  5. def drop_db():
  6. #把Base所有的子类对应表删除。
  7. Base.metadata.drop_all(engine)
  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.  
  6. engine = create_engine("mysql+pymysql://python:python@192.168.0.57:3306/python_mysql", max_overflow=5)
  7.  
  8. Base = declarative_base()
  9.  
  10. # 单表
  11. class Test(Base):
  12. __tablename__ = 'test'
  13. nid = Column(Integer, primary_key=True, autoincrement=True)
  14. name = Column(String(32))
  15.  
  16. # 一对多
  17. class Team(Base):
  18. __tablename__ = 'team'
  19. tid = Column(Integer, primary_key=True, autoincrement=True)
  20. caption = Column(String(32))
  21.  
  22. class user(Base):
  23. __tablename__ = 'user'
  24. nid = Column(Integer, primary_key=True, autoincrement=True)
  25. name = Column(String(32))
  26. team_id = Column(Integer, ForeignKey('team.tid'))
  27.  
  28. def init_db():
  29. Base.metadata.create_all(engine)
  30.  
  31. def drop_db():
  32. Base.metadata.drop_all(engine)
  33.  
  34. init_db()

执行完上面代码后,就会在对应库生成test、user、group三张表,user表的group_id以group表的gid为外键。

1.4 生成表后开始操作表,添加team表数据

  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.  
  6. engine = create_engine("mysql+pymysql://python:python@192.168.0.57:3306/python_mysql", max_overflow=5)
  7.  
  8. Base = declarative_base()
  9.  
  10. # 单表
  11. class Test(Base):
  12. __tablename__ = 'test'
  13. nid = Column(Integer, primary_key=True, autoincrement=True)
  14. name = Column(String(32))
  15.  
  16. # 一对多
  17. class Team(Base):
  18. __tablename__ = 'team'
  19. tid = Column(Integer, primary_key=True, autoincrement=True)
  20. caption = Column(String(32))
  21.  
  22. class user(Base):
  23. __tablename__ = 'user'
  24. nid = Column(Integer, primary_key=True, autoincrement=True)
  25. name = Column(String(32))
  26. team_id = Column(Integer, ForeignKey('team.tid'))
  27.  
  28. def init_db():
  29. Base.metadata.create_all(engine)
  30.  
  31. def drop_db():
  32. Base.metadata.drop_all(engine)
  33.  
  34. # init_db()
  35. # drop_db()
  36.  
  37. Session = sessionmaker(bind=engine)
  38. session = Session()
  39.  
  40. #往team表里插入两条数据
  41. session.add(Team(caption='dba'))
  42. session.add(Team(caption='ddd'))
  43. session.commit()

1.5 添加user表数据

  1. Session = sessionmaker(bind=engine)
  2. session = Session()
  3. #批量添加数据;user表的team_id与team表的tid是有外键的,按理来说要插入的team_id的值必须在team表里有对应的tid值,比如这里插入的tead_id是1、2、3,则team表里的tid至少要有1、2、3,不然会插入失败。
  4. #但是,我发现插入没有对应键值的team_id也不会报错。
  5. session.add_all([
  6. User(name='zzz',team_id=1),
  7. User(name='sss',team_id=2),
  8. User(name='ccc',team_id=3),
  9. ])
  10. session.commit()

1.6 查询单表

如果仅仅是查询user表的name值,那不需要联合别的表,直接查询单表即可

  1. ret = session.query(User).filter(User.name=='zzz').all()
  2. obj = ret[0]
  3. print(obj.name)
  4.  
  5. #上面的代码等价于这个:
  6. ret = session.query(User.name).filter(User.name=='zzz').all()
  7. print(ret)

1.7 通过__repr__()方法改变返回值

  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.  
  6. engine = create_engine("mysql+pymysql://python:python@192.168.0.57:3306/python_mysql", max_overflow=5)
  7.  
  8. Base = declarative_base()
  9.  
  10. # 创建单表
  11. class Users(Base):
  12. __tablename__ = 'users'
  13. id = Column(Integer, primary_key=True)
  14. name = Column(String(32))
  15. extra = Column(String(16))
  16.  
  17. __table_args__ = (
  18. UniqueConstraint('id', 'name', name='uix_id_name'),
  19. Index('ix_id_name', 'name', 'extra'),
  20. )
  21. #__repr__方法是注释的,看print(ret)的输出
  22. #def __repr__(self):
  23. # return "%s-%s" %(self.id, self.name)
  24.  
  25. def init_db():
  26. Base.metadata.create_all(engine)
  27.  
  28. def drop_db():
  29. Base.metadata.drop_all(engine)
  30.  
  31. init_db()
  32.  
  33. Session = sessionmaker(bind=engine)
  34. session = Session()
  35. session.add(Users(id=1,name='zsc'))
  36. session.commit()
  37. ret = session.query(Users).all()
  38. print(ret)
  39. #结果:
  40. [<__main__.Users object at 0x7f1836e80630>]
  41. 没有User类里没有__repr__方法时,session.query(Users).all()返回的是类的对象。
  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.  
  6. engine = create_engine("mysql+pymysql://python:python@192.168.0.57:3306/python_mysql", max_overflow=5)
  7.  
  8. Base = declarative_base()
  9.  
  10. # 创建单表
  11. class Users(Base):
  12. __tablename__ = 'users'
  13. id = Column(Integer, primary_key=True)
  14. name = Column(String(32))
  15. extra = Column(String(16))
  16.  
  17. __table_args__ = (
  18. UniqueConstraint('id', 'name', name='uix_id_name'),
  19. Index('ix_id_name', 'name', 'extra'),
  20. )
  21. #__repr__方法取消注释
  22. def __repr__(self):
  23. return "%s-%s" %(self.id, self.name)
  24.  
  25. def init_db():
  26. Base.metadata.create_all(engine)
  27.  
  28. def drop_db():
  29. Base.metadata.drop_all(engine)
  30.  
  31. init_db()
  32.  
  33. Session = sessionmaker(bind=engine)
  34. session = Session()
  35. session.add(Users(id=1,name='zsc'))
  36. session.commit()
  37. ret = session.query(Users).all()
  38. print(ret)
  39. #结果:
  40. [1-zsc]
  41. User类里定义了__repr__方法时,session.query(Users).all()返回的是定义的返回结果。

1.8 联合查询

  1. #创建表时指定了外键
  2. ret = session.query(User.name).join(Team).all()等价于SELECT user.name AS FROM user INNER JOIN team ON team.tid = user.team_id
  3. #用select的话需要用on指定约束条件,用SQLAlchemy就不用指定了。
  4. #用“isouter=True”指定left join
  5. ret = session.query(User.name).join(Team,isouter=True).all()

上面的查询,随便是依赖到了别的表,但是结果只是显示了user表的数据,如果想同时显示user和team表的数据,就得用下面的方法了,

  1. ret = session.query(User.name,Team.caption).join(Team).all()
  2. print(ret)
  3. #结果:
  4. [('zzz', 'dba'), ('sss', 'ddd')]

虽然上面的联合查询已经比直接用select简单了,但是还是很麻烦,所以就有了下面的方法。

1.9 relationship

1.9.1 利用ralationship正向查询

正向查询即是使用做外链的表来查询被外链里的数据

  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.  
  6. engine = create_engine("mysql+pymysql://python:python@192.168.0.57:3306/python_mysql", max_overflow=5)
  7.  
  8. Base = declarative_base()
  9.  
  10. # 一对多
  11. class Team(Base):
  12. __tablename__ = 'team'
  13. tid = Column(Integer, primary_key=True, autoincrement=True)
  14. caption = Column(String(32))
  15.  
  16. class User(Base):
  17. __tablename__ = 'user'
  18. nid = Column(Integer, primary_key=True, autoincrement=True)
  19. name = Column(String(32))
  20. team_id = Column(Integer, ForeignKey('team.tid'))
  21. #加上底下这行后,不用使用.join()也可实现联表查询
  22. #哪个表做外链,就把relationship加到哪个表
  23. favor = relationship("Team", backref='uuu')
  24.  
  25. def init_db():
  26. Base.metadata.create_all(engine)
  27.  
  28. def drop_db():
  29. Base.metadata.drop_all(engine)
  30.  
  31. # init_db()
  32. # drop_db()
  33.  
  34. Session = sessionmaker(bind=engine)
  35. session = Session()
  36.  
  37. ret = session.query(User).all()
  38. for obj in ret:
  39. print(obj.nid,obj.name,obj.favor,obj.favor.tid,obj.favor.caption)
  40. #结果:
  41. 1 zzz <__main__.Team object at 0x7f5c10d02a20> 1 dba
  42. 2 sss <__main__.Team object at 0x7f5c10d026a0> 2 ddd
  43.  
  44. #可见,ret仅仅是User的query结果,而使用obj.favor就相当于是使用Team表,即可直接操作team表。

1.9.2 利用ralationship实现反向查询

反向查询即是使用被外链的表查询到做外链的数据

  1. class Test(Base):
  2. __tablename__ = 'test'
  3. nid = Column(Integer, primary_key=True, autoincrement=True)
  4. name = Column(String(32))
  5.  
  6. # 一对多
  7. class Team(Base):
  8. __tablename__ = 'team'
  9. tid = Column(Integer, primary_key=True, autoincrement=True)
  10. caption = Column(String(32))
  11.  
  12. class User(Base):
  13. __tablename__ = 'user'
  14. nid = Column(Integer, primary_key=True, autoincrement=True)
  15. name = Column(String(32))
  16. team_id = Column(Integer, ForeignKey('team.tid'))
  17. favor = relationship("Team", backref='uuu')
  18.  
  19. def init_db():
  20. Base.metadata.create_all(engine)
  21.  
  22. def drop_db():
  23. Base.metadata.drop_all(engine)
  24.  
  25. # init_db()
  26. # drop_db()
  27.  
  28. Session = sessionmaker(bind=engine)
  29. session = Session()
  30.  
  31. ret = session.query(Team).filter(Team.caption == 'dba').all()
  32. print(ret[0].tid)
  33. print(ret[0].caption)
  34. print(ret[0].uuu)
  35. #结果:
  36. 1
  37. dba
  38. [<__main__.User object at 0x7f7d3fa5ba20>]
  39. #favor = relationship("Team", backref='uuu')里的uuu的作用就是存储着对应的做外链里的数据;比如user里有7个人是dba组的,这时候print(ret[0].uuu)就会返回7个用户的信息;user里有3个dbb组的,这时候print(ret[0].uuu)就会返回3个相关用户的信息。

除了一对多还是多对多关系,多对多是专门建一个中间表来存储两张表的关联关系。

SQLAlchemy看着麻烦,其实就是记语法而已,多用即可;

先建表,再操作单表,再用连表,在整关系,一对多,多对多。

SQLAlchemy一对多总结的更多相关文章

  1. flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询

    一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生. 一对多查询 如果一个 ...

  2. sqlalchemy一对多的关系

    #encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text ...

  3. SQLAlchemy 一对多

    下述範例描述了電影同導演的多對一關係.範例中說明了從用戶定義的Python類建立數據表的方法,雙方關係例項的建立方法,以及最終查詢數據的方法:包括延遲載入和預先載入兩種自動生成的SQL查詢. 結構定義 ...

  4. flask 中orm关系映射 sqlalchemy的查询

    flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询   一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课 ...

  5. 应有dataGridView控件

    using System.Data.SqlClient; namespace UseDataGridView { public partial class Form1 : Form { public ...

  6. [ Flask ] myblog_flask问题集(RESTfull风格)

    VUE问题 前端VUE怎么捕获所有404NOT FOUND的路由呢? [ 解决方案 ] vue-router路由守卫,参考文档:动态路由匹配 对于路由.../edit/<id>,自己能编辑 ...

  7. flask SQLAlchemy中一对多的关系实现

    SQLAlchemy是Python中比较优秀的orm框架,在SQLAlchemy中定义了多种数据库表的对应关系, 其中一对多是一种比较常见的关系.利用flask sqlalchemy实现一对多的关系如 ...

  8. SQLAlchemy 增删改查 一对多 多对多

    1.创建数据表 # ORM中的数据表是什么呢? # Object Relation Mapping # Object - Table 通过 Object 去操纵数据表 # 从而引出了我们的第一步创建数 ...

  9. 用SQLAlchemy创建一对多,多对多关系表

    多对多关系表的创建: 如果建立好多对多关系后,我们就可以通过关系名进行循环查找,比如laowang = Teacher.query.filter(Teacher.name=='laowang').fi ...

随机推荐

  1. 普华永道高级JAVA面试记录

    最近在考虑换个工作 原因?咱能不逗吗? 一面感觉发挥不错  二面之后累觉不爱  基本上浪费了半天的工资(好多钱啊~~~) PWD上海地址在浦东软件园  工作环境说实话没我现在工作的环境好,不过里面的人 ...

  2. 控制边框颜色:《CSS3 Border-color》

    CSS3中有关于Border的属性一共有三个:圆角border-radius,图片边框border-images,边框多颜色border-color,其中圆角border-radius是常用的一个属性 ...

  3. Android动画View Animation

    Animations 一.Animations介绍 Animations是一个实现android UI界面动画效果的API,Animations提供了一系列的动画效果,可以进行旋转.缩放.淡入淡出等, ...

  4. VS2012下基本类型大小

  5. C++库汇总

    C++库汇总 C++类库介绍再次体现了C++保持核心语言的效率同时大力发展应用库的发展趋势!!在C++中,库的地位是非常高的.C++之父 Bjarne Stroustrup先生多次表示了设计库来扩充功 ...

  6. 使用VB6制作RTD函数

    以前模仿大神在vs里使用c#实现RTD函数功能.(真是很生僻的东东啊)C#制作RTD参考:大神博客跳转.最近想VB里能不能做?就试着做了做,好像基本成了,整套代码有些毛病,勉强能算个样子,暂时不打算再 ...

  7. SQL&&LINQ:左(外)连接,右(外)连接,内连接,完全连接,交叉连接,多对多连接

    SQL: 外连接和内连接: 左连接或左外连接:包含左边的表的所有行,如果右边表中的某行没有匹配,该行内容为空(NULL) --outer jion:left join or left outer jo ...

  8. 视频播放器之————JW Player参数详解

    JW Player参数详解 1,安装 下载后,你可以得到一个例子,当用文本或HTML编辑器打开的时候,你可以发现swf是用一段短小的 javascript嵌入到页面上的.这个Javascript是Ge ...

  9. UART总线(异步)

    UART用一条传输线将数据一位位地顺序传送,以字符为传输单位通信中两个字符间的时间间隔多少是不固定的, 然而在同一个字符中的两个相邻位间的时间间隔是固定的 数据传送速率用波特率来表示, 指单位时间内载 ...

  10. 转:画图解释 SQL join 语句

    画图解释 SQL join 语句 我认为 Ligaya Turmelle 的关于SQL联合(join)语句的帖子对于新手开发者来说是份很好的材料.SQL 联合语句好像是基于集合的,用韦恩图来解释咋一看 ...