资讯专栏INFORMATION COLUMN

sqlalchemy 配置多连接读写库后的关系设置

Tony_Zby / 686人阅读

摘要:前言一般来说解决连接多个库的最简单的方式是新建两个或多个相互没有关联配置不同的来连接这样的话正常配置就行不用特殊配置如果这样解决的话也就不用看下面的配置了不可以加上如下的五种方式都是可以的这个配置很关键很关键这个配置很关键用户工

前言

一般来说,解决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"))   # 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)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43929.html

相关文章

  • Flask Web Development —— 数据库(中)

    摘要:关系关系数据库通过使用关系在不同的表中建立连接。以下部分将介绍最常见的数据库操作。如果数据库已存在函数不会重新创建或更新数据库表。到目前为止对象只存于中,他们还没有被写入数据库。数据库会话也叫事务。删除行数据库会话同样有方法。 7、关系 关系数据库通过使用关系在不同的表中建立连接。图像5-1的关系图表达了用户和用户角色之间的简单关系。这个角色和用户是一对多关系,因为一个角色可以从属于...

    April 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<