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 数据库连接数飙升,在高并 ...
随机推荐
- 《C语言程序设计(第四版)》阅读心得(一)
本篇开始写我个人觉得谭浩强老师的<C语言程序设计(第四版)>中之前没有认识到,或者忘了的知识.因为本科学过,所以有些简单的东西就没有放进来了,所以可能并不是太全面. 第一章程序设计与语言 ...
- ProxySQL Tutorial : setup in a MySQL replication topology
ProxySQL Tutorial : setup in a MySQL replication topology 时间 2015-09-15 05:23:20 ORACLE数据库技术文刊 原文 h ...
- C++对拍数据生成
#include<map> #include<ctime> #include<queue> #include<cmath> #include<cs ...
- Ubuntu 16.04使用百度云的方案
Ubuntu没有很好的解决方案,都是一些投机取巧的方案: 1.不建议安装百度云客户端,尤其对于免费用户来说,会限制速度. 2.可以使用网页版进行文件上传. 3.下载可以通过Chrome点击下载后,复制 ...
- Ubuntu 16.04安装磁盘占用分析器:ncdu
使用此工具能分析出哪个文件或者文件夹有多大,从而实现自己手动删除. 安装: sudo apt-get install ncdu 使用: #默认搜索当前用户目录 ncdu #搜索整个硬盘 ncdu /
- [52ABP系列] - 002、模板项目配合代码生成器开发
前言 本篇的主要内容是 52ABP SPA模板如何配合52ABP代码生成器开发项目 如果不了解 52ABP 项目请先看我的第一篇文章 [52ABP系列] - 001.SPA免费项目模版搭建教程 话不多 ...
- Python标准库:内置函数tuple([iterable])
本函数实现从可迭代对象生成一个元组对象返回.元组对象是一个不可改动的列表对象. 样例: #tuple() print(tuple([1, 2, 3])) print(tuple((1, 2, 3))) ...
- Hadoop-mapreduce 程序在windows上执行需要注意的问题
1.在主程序中需要添加这几个参数配置 Configuration conf = new Configuration(); // 1.设置job运行时要访问的默认文件系统 conf.set(" ...
- JAVA编程思想(2) - 操作符(二)
5. 直接常量 -一般来说,假设程序里使用了"直接常量",编译器能够准确的知道要生成什么样的类型.但有时候却是模棱两可的. 这时候须要我们对编译器进行适当的"指导&quo ...
- Android 跑马灯效果与EditText冲突
近期一个项目,因为布局TextView内容太长了.首先想到的就是跑马灯效果,所以就把TextView又一次自己定义了,尽管跑马灯效果实现了.只是导致了还有一个问题就是EditText输入问题,当第一次 ...