sqlalchemy配置多读写库多连接后的关系设置
前言
一般来说,解决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配置多读写库多连接后的关系设置的更多相关文章
- plsql连接oralce数据的配置 PLSQL配置怎么连ORACLE plsql连接多个数据库设置 Oracle 服务命名(别名)的配置及原理,plsql连接用
Oracle 服务命名(别名)的配置及原理,plsql连接用 Oracle 服务命名(别名)的配置及原理 连接数据库必须配置服务命名(别名,用于plsql的连接),不管是本地还是远程,服务命名即简单命 ...
- 使用ThreadLocal实现的读写分离在迁移后的偶发错误
最近莫名的会有错误日志,说有写操作因为走了读库而报了read only的异常,由于并没有造成应用使用的问题,开始我以为哪的配置错误就没当回事让程序员自己去查了,然而... 背景:之前的博客里提到过,读 ...
- MySQL8.0.12 安装及配置、读写分离,主从复制
一.安装 1.从网上下载MySQL8.0.12版本,下载地址:https://dev.mysql.com/downloads/mysql/ 2. 下载完成后解压 我解压的路径是:D:\Java\mys ...
- Oracle备库TNS连接失败的分析
今天在测试12c的temp_undo的时候,准备在备库上测试一下,突然发现备库使用TNS连接竟然失败. 抛出的错误如下: $ sqlplus sys/oracle@testdb as sysdba S ...
- IIS7下配置SSAS通过HTTP远程连接
淘宝 问答 学院 博客 资源下载 高端培训 登录 注册 全部问题 文章 话题 人物 ...
- Openmpi 编译安装+集群配置 + Ubuntu14.04 + SSH无密码连接 + NFS共享文件系统
来源 http://www.open-mpi.org/ 网络连接 SSH连接,保证各台机器之间可以无密码登陆,此处不展开 hosts文件如下 #/etc/hosts 192.168.0.190 mas ...
- ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(三)
ubuntu18.04配置nvidia docker和远程连接ssh+远程桌面连接(三) 本教程适用于想要在远程服务器上配置docker图形界面用于深度学习的用户. (三)配置远程桌面连接访问dock ...
- tomcat7.0.55配置单向和双向HTTPS连接
HTTPS配置中分为单向连接和双向连接,单向连接只需要服务器安装证书,客户端不需要,双向连接需要服务器和客户端都安装证书 下面的配置都没有用CA签名来配置,都不能用于生产环境,实际配置中是需要CA的, ...
- django 重写 mysql 连接库实现连接池
django 重写 mysql 连接库实现连接池 问题 django 项目使用 gunicorn + gevent 部署,并设置 CONN_MAX_AGE 会导致 mysql 数据库连接数飙升,在高并 ...
随机推荐
- Leetcode 220.存在重复元素III
存在重复元素III 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ. ...
- expdp,impdp,include,exclude
The examples below are based on:- the demo schema SCOTT that is created with script: $ORACLE_HOME/rd ...
- CSU 1214 找最大异或值
题目大意: 给定一堆数,从中找2个数异或得到的最大值 直接暴力会超时,我们要考虑对于每一个数去匹配找到异或的最大值,我们希望2进制越前面的数尽可能都为1 所以我们用 0-1 字典树保存这些数,因为一个 ...
- fzu 2113 数位dp
#include<stdio.h> #include<string.h> #define N 20 #define ll __int64 ll dp[N][N];//最多记忆4 ...
- cdq分治入门--BZOJ3262: 陌上花开
n<=100000个人,每个人三个属性Ai,Bi,Ci,一个人i的等级为Ai>=Aj,Bi>=Bj,Ci>=Cj的人数,求每个等级有多少人. 裸的三维偏序.按照常规思路,一维排 ...
- Java内存分配与参数传递
JAVA中方法的参数传递方式只有一种:值传递. JAVA内存分配: 1.栈:存放 基本类型的数据.对象的引用(类似于C语言中的指针) 2.堆:存放用new产生的数据 3.静态域:存放在对象中用stat ...
- Eclipse 远程tomcat调试程序
Eclipse 远程tomcat调试程序 很多时候我们把代码部署到云服务器上,需要调试的时候可以选择远程调试,既节省时间,效率又高.下面详细介绍如何进行远程调试. 1.1. 创建startup-deb ...
- Excel数据字典转换为PDM(且显示表名、字段相应的中文描写叙述)
在工作中遇到了一个问题就是把Excel数据字典转换为PDM. 可是转换完毕了全是英文,原来对表名.字段名的中文描写叙述就没有了. 且对于这个问题在powerdesigner15.2以后能够直接完毕.可 ...
- C中多线程开发
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期.solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,可是在一个进程(proce ...
- iOS中.pch文件怎样使用
pch 能够用来存储共享信息,比方设备屏幕的宽度,高度.版本等等 公用信息 Xcode 老版本号会自己主动为我们创建pch文件,新版本号開始不自己主动创建了.假设须要使用能够自己手动创建 waterm ...