多对一,一对多

  1. class Project(db.Model):
  2. id = db.Column(db.Integer, primary_key=True)
  3. name = db.Column(db.String(80))
  4. # modules = db.relationship('Module',backref='project')
  5. modules = db.relationship('Module', back_populates='module_project')
  6. class Module(db.Model):
  7. id = db.Column(db.Integer, primary_key=True)
  8. name = db.Column(db.String(80))
  9. project_id = db.Column(db.Integer, db.ForeignKey("project.id"))
  10. module_project = db.relationship('Project', back_populates='modules')

modules,module_project 字段与DB中的表是没有关系的,只是在orm对象间进行使用。

relationship参数解释

param1,指明与哪个模型类产生联系
modules 作用是通过modules这一个属性来查询到关联的表的属性 ex project.modules,可自行命名,方便使用即可。
backref 反向引用,当已经查到一个module的时候如何获取对应的project module.project
backref 的缺点在于可读性不够强。反向引用只需要在一方定义,只需要声明关系即可
back_populates 显式的说明两张表的关系,这种方法是显示对应的,多方与单方都需要进行配置,可以提高健壮性,如果定义错误既会报错

backref vs back_populates

back_populates 需要双向显式说明,backref 只需要指明一遍隐式说明即可
back_populates 更麻烦,backref更简单
back_populates 更具有可读性,能很快知道各个表之间的关系

一对一

  1. class Project(db.Model):
  2. id = db.Column(db.Integer, primary_key=True)
  3. name = db.Column(db.String(80))
  4. # modules = db.relationship('Module',backref='project')
  5. modules = db.relationship('Module', backref='module_project', uselist=False)

加上userlist=False就变成1对1的对应关系

多对多

适用场景

1,关系表值存储2个关联表的id作为外键,没有其他信息
2,关系表不能祖籍为模型操作

  1. # 多对多,中间表
  2. xuanke = db.Table("xuanke", db.column('user_id', db.Integer, db.ForeignKey('user.id')),
  3. db.ForeignKey('subject_id'), db.Integer, db.ForeignKey('subject.id'))
  4. class Subject(db.Model):
  5. id = db.Column(db.Integer,primary_key=True)
  6. name = db.Column(db.String(20))
  7. class User(db.Model):
  8. id = db.Column(db.Integer,primary_key=True)
  9. name = db.Column(db.String(20))
  10. subjects = db.relationship("Subject",secondary=xuanke,
  11. backref=db.backref('users',lazy='dynamic'))

relationship参数解释

1,第一个参数,与哪个模型类产生关系
2,secondary 参数就是关系表 db.Table 声明一个表,该表不能通过orm直接使用,不可单独对词表进行查询
只能根据多对多关系查询到目标数据。

  • secondary 接收的参数为db.Table声明的中间表对象,
  • lazy日后理解

    自引用关系

    flask上下文机制

    如果出现 outside context error 则是出现了关于flask上下文环境的问题,即 request,g,app,之类的全局变量脱离请求环境是无法访问的。
    RequestContext() 请求上下文
    AppContext() 应用上下文
    来看一张图片
    未命名文件.png
    上图锁展示的是flask发送请求的流程,以及内部处理逻辑。
    当一个flask请求进来之后,存储在环境变量envior中,请求会调用flask中的最小原形中的app.call方法里面的wsgi_app()方法初始化一个RequestContext(environ)并进行判断是否已生成上下文,生成则执行 ctx.push()将这个上下文推入一个栈中。 ```python

1,最小原形里面的app 是一个函数, 而flask 是对象,对象被调用是执行call方法 2,app.call 里面的函数 wsgi_app() 3, wsgi_app原码 会通过环境变量数据实例化一个 RequestContext(environ) 并执行ctx.push() 将这个请求上下文推入一个栈中 4,request_ctx.push() 先判断一下是否有一个 appContext 没有的话推入一个 5,_request_ctx_stack.top 就是现在的请求对象 6,_app_ctx_stack.top 就是现在的app对象 7,_request_ctx_stack.top 就是current_app 8, _app_ctx_stack.top 就是request ```