前言

一般来说,解决sqlalchemy 连接多个库的最简单的方式是新建两个或多个db.session 相互没有关联,modle配置不同的db.session来连接,这样的话,relationship正常配置就行,不用特殊配置.如果这样解决的话,也就不用看下面的配置了

# -*- coding:utf-8 -*-

import flask
from flask_sqlalchemy import SQLAlchemy # Flask-SQLAlchemy 2.3.2
from datetime import datetime
from sqlalchemy.orm import backref, foreign # SQLAlchemy 1.3.1 app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_BINDS'] = {
'read_db': 'mysql://reader:test@127.0.0.1:3306/test?charset=utf8',
'write_db': 'mysql://writer:test@127.0.0.2:3306/test?charset=utf8'
} app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ECHO'] = False
db = SQLAlchemy(app) class RDriver(db.Model):
__bind_key__ = 'read_db'
__tablename__ = 'driver'
# __table_args__ = {'schema': 'test'} # 不可以加上 id = db.Column(db.Integer, primary_key=True, autoincrement=True)
fk_user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
driver_name = db.Column(db.String(7))
create_time = db.Column(db.TIMESTAMP, default=datetime.now) class RUser(db.Model):
__bind_key__ = 'read_db'
__tablename__ = 'user'
# __table_args__ = {'schema': 'test'} id = db.Column(db.Integer, primary_key=True, autoincrement=True)
user_name = db.Column(db.String(32), index=True, unique=True)
user_password = db.Column(db.String(32))
create_time = db.Column(db.TIMESTAMP, default=datetime.now)
update_time = db.Column(db.TIMESTAMP, default=datetime.now)
# 如下的五种方式都是可以的
# driver_fk = db.relationship("RDriver", foreign_keys='RDriver.fk_user_id')
# driver_fk = db.relationship("RDriver", primaryjoin=lambda: RDriver.fk_user_id == RUser.id, viewonly=True)
# driver_fk = db.relationship("RDriver", primaryjoin=RDriver.fk_user_id == id)
fk_driver = db.relationship("RDriver", primaryjoin='RDriver.fk_user_id == RUser.id')
# driver_fk = db.relationship("RDriver", backref=db.backref('user', lazy=True),
# primaryjoin=lambda: RDriver.fk_user_id == RUser.id, viewonly=True) class WDriver(db.Model):
__bind_key__ = 'write_db'
__tablename__ = 'driver'
__table_args__ = {'schema': 'test', 'extend_existing': True} id = db.Column(db.Integer, primary_key=True, autoincrement=True)
fk_user_id = db.Column(db.Integer, db.ForeignKey("test.user.id"))
plate = db.Column(db.String(7))
create_at = db.Column(db.TIMESTAMP, default=datetime.now) class WUser(db.Model):
__bind_key__ = 'write_db'
__tablename__ = 'user'
__table_args__ = {'schema': 'test', 'extend_existing': True} id = db.Column(db.Integer, primary_key=True, autoincrement=True)
hash = db.Column(db.String(256), nullable=False)
user_no = db.Column(db.String(32), index=True, unique=True) # 用户工号
create_time = db.Column(db.TIMESTAMP, default=datetime.now)
update_time = db.Column(db.TIMESTAMP, default=datetime.now)
# 以下五种方式都是可以的
# fk_driver = db.relationship("WDriver", foreign_keys='WDriver.fk_user_id', uselist=False)
# fk_driver = db.relationship("WDriver", primaryjoin=lambda: WDriver.fk_user_id == WUser.id)
fk_driver = db.relationship("WDriver", primaryjoin=WDriver.fk_user_id == id)
# fk_driver = db.relationship("WDriver", primaryjoin='WDriver.fk_user_id == WUser.id')
# fk_driver = db.relationship("WDriver", backref=db.backref('test.user', lazy=True),
# primaryjoin=lambda: WDriver.fk_user_id == WUser.id) r_user_obj = RUser.query.filter_by().first()
print("r_user_obj:", r_user_obj)
print("r_user_obj.driver_fk:", r_user_obj.fk_driver)
w_user_obj = WUser.query.filter_by(id=2188).first()
print("w_user_obj:", w_user_obj)
print("w_user_obj.driver_fk:", w_user_obj.fk_driver)

参考文档:

* https://docs.sqlalchemy.org/en/13/orm/relationship_api.html # 值得细看
* https://www.osgeo.cn/sqlalchemy/orm/relationship_api.html # 同上,中文
* https://www.cnblogs.com/srd945/p/9851227.html
* extend_existing: (False)当表已经存在于元数据中时,如果元数据中存在与column_list中的列同名的列,column_list中同名的列会替换掉元数据中已经有的列
* useexisting已被废弃, 新版本使用extend_existing

总结

关系配置参数真的很多,如下,很容易就会出错,需要多读读官方文档,还有就是建立modle时候尽量简洁,风格统一,不要在数据库层建立外键.

sqlalchemy.orm.relationship(argument, secondary=None, primaryjoin=None, secondaryjoin=None, foreign_keys=None,
uselist=None, order_by=False, backref=None, back_populates=None, post_update=False, cascade=False, extension=None,
viewonly=False, lazy='select', collection_class=None, passive_deletes=False, passive_updates=True, remote_side=None,
enable_typechecks=True, join_depth=None, comparator_factory=None, single_parent=False, innerjoin=False,
distinct_target_key=None, doc=None, active_history=False, cascade_backrefs=True, load_on_pending=False,
bake_queries=True, _local_remote_pairs=None, query_class=None, info=None, omit_join=None)

sqlalchemy配置多读写库多连接后的关系设置的更多相关文章

  1. plsql连接oralce数据的配置 PLSQL配置怎么连ORACLE plsql连接多个数据库设置 Oracle 服务命名(别名)的配置及原理,plsql连接用

    Oracle 服务命名(别名)的配置及原理,plsql连接用 Oracle 服务命名(别名)的配置及原理 连接数据库必须配置服务命名(别名,用于plsql的连接),不管是本地还是远程,服务命名即简单命 ...

  2. 使用ThreadLocal实现的读写分离在迁移后的偶发错误

    最近莫名的会有错误日志,说有写操作因为走了读库而报了read only的异常,由于并没有造成应用使用的问题,开始我以为哪的配置错误就没当回事让程序员自己去查了,然而... 背景:之前的博客里提到过,读 ...

  3. MySQL8.0.12 安装及配置、读写分离,主从复制

    一.安装 1.从网上下载MySQL8.0.12版本,下载地址:https://dev.mysql.com/downloads/mysql/ 2. 下载完成后解压 我解压的路径是:D:\Java\mys ...

  4. Oracle备库TNS连接失败的分析

    今天在测试12c的temp_undo的时候,准备在备库上测试一下,突然发现备库使用TNS连接竟然失败. 抛出的错误如下: $ sqlplus sys/oracle@testdb as sysdba S ...

  5. IIS7下配置SSAS通过HTTP远程连接

    淘宝 问答 学院 博客 资源下载 高端培训                  登录 注册                                   全部问题 文章 话题 人物         ...

  6. Openmpi 编译安装+集群配置 + Ubuntu14.04 + SSH无密码连接 + NFS共享文件系统

    来源 http://www.open-mpi.org/ 网络连接 SSH连接,保证各台机器之间可以无密码登陆,此处不展开 hosts文件如下 #/etc/hosts 192.168.0.190 mas ...

  7. ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(三)

    ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(三) 本教程适用于想要在远程服务器上配置docker图形界面用于深度学习的用户. (三)配置远程桌面连接访问dock ...

  8. tomcat7.0.55配置单向和双向HTTPS连接

    HTTPS配置中分为单向连接和双向连接,单向连接只需要服务器安装证书,客户端不需要,双向连接需要服务器和客户端都安装证书 下面的配置都没有用CA签名来配置,都不能用于生产环境,实际配置中是需要CA的, ...

  9. django 重写 mysql 连接库实现连接池

    django 重写 mysql 连接库实现连接池 问题 django 项目使用 gunicorn + gevent 部署,并设置 CONN_MAX_AGE 会导致 mysql 数据库连接数飙升,在高并 ...

随机推荐

  1. hdu 4770 状压+枚举

    /* 长记性了,以后对大数组初始化要注意了!140ms 原来是对vis数组进行每次初始化,每次初始化要200*200的复杂度 一直超时,发现没必要这样,直接标记点就行了,只需要一个15的数组用来标记, ...

  2. 2015山东信息学夏令营 Day5T3 路径

    问题描述: 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入: 第一行包含一个正整数n,表示点数. 接下来 ...

  3. javabean组件

    javaBean组件引入: javaBean是使用java语言开发的一个可重用的组件,在Jsp开发中可以使用javaBean减少重复代码,使整个JSP代码的开发更简洁. 我们首先创建一个类叫做Stud ...

  4. UIButton图片文字位置的四种情况

    我们在做项目的过程中经常会遇到各定制UIButton 1.左边图片,右边文字 2.左边文字,右边图片 3.上边图片,下边文字 4.上边文字,下边图片 针对这四种情况 使用UIButton的catego ...

  5. 获取select 选中的option中自定义的名称的之

    <select style="width: 220px;height: 20px;margin: 0 0 0 20px;" id="invest_ticket&qu ...

  6. [Java Spring] Spring Annotation Configuration Using XML

    Add context to our application. main/resources/applicationContext.xml: <?xml version="1.0&qu ...

  7. 第6章1节《MonkeyRunner源代码剖析》Monkey原理分析-事件源-事件源概览

    在上一章中我们有简要的介绍了事件源是怎么一回事.可是并没有进行详细的描写叙述.那么往下的这几个小节我们就须要把这方面的知识给补充完整. 这一节我们先主要环绕MonkeySourceNetwork这个事 ...

  8. quick-cocos2d-x游戏开发【1】——引擎结构总览和创建项目

    好吧,我还是忍不住想写点关于quick的学习笔记,确实网上关于它的教程太少太少了,简单把自己的所学所得分享一下,有不正确之处还请拍砖. 首先下载引擎包.触控收购quick之后.如今cocos中文站的主 ...

  9. netty4与protocol buffer结合简易教程

    各项目之间通常使用二进制进行通讯,占用带宽小.处理速度快~ 感谢netty作者Trustin Lee.让netty天生支持protocol buffer. 本实例使用netty4+protobuf-2 ...

  10. div拖拽缩放jquery插件编写——带8个控制点

    项目中需要对div进行拖拽缩放,需要有控制面板8个控制点的那种,原以为这么常见的效果应该能搜索到很多相关插件,然而可以完成拖拽的实繁,却找不到我想要的,还是自己动手丰衣足食吧 效果预览(只支持pc端) ...