前言

一般来说,解决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. NYOJ-769乘数密码,逆元解法;

    乘数密码 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 ->    Link    <- 简单代替密码的第二种,比移位密码稍微复杂点,不过鉴于NYOJ,是完全可以 ...

  2. Flask(1):基本示例、配置文件、路由、请求和响应、模板渲染

    Flask的特点: - pip install flask - 短小精悍.可扩展性强的 web框架 注意:上下文管理机制 - 依赖 wsgi:werkzeug Flask的简单示例: from fla ...

  3. es6常用语法和特性

    简介 首先,在学习之前推荐使用在线转码器 Traceur 来测试 Demo,避免 babel 下的繁琐配置,从而产生畏难情绪. let 命令 在 ES6 之前,JS 只能使用 var 声明变量,或者省 ...

  4. Android 网络连接状态的监控

    有些应用需要连接网络,例如更新后台服务,刷新数据等,最通常的做法是定期联网,直接使用网上资源.缓存数据或执行一个下载任务来更新数据. 但是如果终端设备没有连接网络,或者网速较慢,就没必要执行这些任务. ...

  5. Spring Boot - how to configure port

    https://stackoverflow.com/questions/21083170/spring-boot-how-to-configure-port

  6. python之练习-三层菜单

    今天练习编写显示3层城市名称并可以返回上一层以及退出程序. Readme: 程序概述1:程序名称为:menu_three.py2:记录省,市,县的原始文件名为:areafile3:areafile文件 ...

  7. Meeting 加虚拟边

    Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his fence ...

  8. P1165 日志分析 洛谷

    https://www.luogu.org/problem/show?pid=1165 题目描述 M 海运公司最近要对旗下仓库的货物进出情况进行统计.目前他们所拥有的唯一记录就是一个记录集装箱进出情况 ...

  9. java反射-使用反射来操纵方法

    一个类的主要成员时方法,辣么我们通过反射获取到一个类的所有方法信息后,总的寻找一种方式去操作调用这些方法,这样反射才有意义有意思. Method对象有一个方法invoke.      public O ...

  10. spring面试相关点

    刚刚开通博客,因为最近在进行各种面试,遇到各种面试问题,用这个机会整理几篇文章方便日后需要 springmvc 和springboot spring boot只是一个配置工具,整合工具,辅助工具. s ...