SQLAlchemy配置连接多个数据库

 1.定义配置项


首先定义两个数据库的配置信息

# PostgreSQL database configuration
DB_USERNAME=postgres
DB_PASSWORD=passord
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=test

# mysql database configuration
DB_USERNAME_MYSQL=root
DB_PASSWORD_MYSQL=password
DB_HOST_MYSQL=127.0.0.1
DB_PORT_MYSQL=3306
DB_DATABASE_MYSQL=test

2.定义Config类

首先读取上面的数据库配置项。

“db_credentials ”和“db_mysql_credentials”是我储存对应数据库配置的自定义字段,随意起名即可。

“self.SQLALCHEMY_DATABASE_URI”字段名代表sqlalchemy的主数据库,这里我使用的是postgres,里面按照文档要求填上对应的请求地址。

“self.SQLALCHEMY_BINDS”可以理解为副数据库,可以把其他数据库都写在这里,其值是dict格式。格式为{"key":"databaseUri"}。每个数据库都必须以唯一的键值区分,键值按自己喜好取就行。mysql1,mysql2,mysql3什么的....

"self.SQLALCHEMY_ENGINE_OPTIONS"代表连接池大小

“self.SQLALCHEMY_ECHO”代表sqlalchemy在每次请求时是否在控制台打印sql语句

注意:

SQLAlchemy采用的是加载对应数据库DBAPI 的方式来连接的,而具体加载哪个DBAPI 是你在数据库URI中声明的,如“mysql+pymysql”代表使用PyMySQL连接mysql,也就是说你需要先安装PyMySQL库。这其实和使用java时用JDBC映射的方式连接mysql很像

pip install PyMySQL

Config代码内容:

class Config:
    """Application configuration class."""

    def __init__(self):
  
        # ------------------------
        # Database Configurations.
        # ------------------------
        db_credentials = {
            key: get_env(key) for key in
            ['DB_USERNAME', 'DB_PASSWORD', 'DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_CHARSET']
        }
        self.SQLALCHEMY_DATABASE_URI_SCHEME = get_env('SQLALCHEMY_DATABASE_URI_SCHEME')
        db_extras = f"?client_encoding={db_credentials['DB_CHARSET']}" if db_credentials['DB_CHARSET'] else ""
        self.SQLALCHEMY_DATABASE_URI = f"{self.SQLALCHEMY_DATABASE_URI_SCHEME}://{db_credentials['DB_USERNAME']}:{db_credentials['DB_PASSWORD']}@{db_credentials['DB_HOST']}:{db_credentials['DB_PORT']}/{db_credentials['DB_DATABASE']}{db_extras}"

        db_mysql_credentials = {
            key: get_env(key) for key in
            ['DB_USERNAME_MYSQL', 'DB_PASSWORD_MYSQL', 'DB_HOST_MYSQL', 'DB_PORT_MYSQL', 'DB_DATABASE_MYSQL']
        }

        # password = db_mysql_credentials['DB_PASSWORD_MYSQL']
        # pwd = parse.quote_plus(password)
        self.SQLALCHEMY_BINDS = {
            "mysqlkey": f"mysql+pymysql://{db_mysql_credentials['DB_USERNAME_MYSQL']}:{db_mysql_credentials['DB_PASSWORD_MYSQL']}@{db_mysql_credentials['DB_HOST_MYSQL']}:{db_mysql_credentials['DB_PORT_MYSQL']}/{db_mysql_credentials['DB_DATABASE_MYSQL']}?charset=utf8mb4"
        }
        self.SQLALCHEMY_ENGINE_OPTIONS = {
            'pool_size': int(get_env('SQLALCHEMY_POOL_SIZE')),
            'max_overflow': int(get_env('SQLALCHEMY_MAX_OVERFLOW')),
            'pool_recycle': int(get_env('SQLALCHEMY_POOL_RECYCLE')),
            'pool_pre_ping': get_bool_env('SQLALCHEMY_POOL_PRE_PING'),
            'connect_args': {'options': '-c timezone=UTC'},
        }

        self.SQLALCHEMY_ECHO = get_bool_env('SQLALCHEMY_ECHO')

3.初始化SQLAlchemy

编写好Config类后,就可以初始化sqlalchemy了。

from flask_sqlalchemy import SQLAlchemy
from myconfig import Config
from flask import Flask
import flask_migrate
 
 
app = Flask()
 
app.config.from_object(Config())
 
db = SQLAlchemy()
 
db.init_app(app)
 
flask_migrate.Migrate(app, db)

4.定义不同数据库的表结构

如果表所对应的数据库是通过“self.SQLALCHEMY_DATABASE_URI”字段绑定到SQLAlchemy上的,那么它所对应的类不需要做额外的修改,SQLAlchemy默认使用主数据库。

 

from flask_sqlalchemy import SQLAlchemy
 
db = SQLAlchemy()
 
class Setup(db.Model):
    __tablename__ = 'setups'
    __table_args__ = (
        db.PrimaryKeyConstraint('version', name='setup_pkey'),
    )
 
    version = db.Column(db.String(255), nullable=False)
    setup_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)'))

如果表所对应的数据库是通过“self.SQLALCHEMY_BINDS”字段的方式绑定到SQLAlchemy上的,那么就需要在类的开头用__bind_key__声明这张表是在哪一个数据库上,值填写你在“self.SQLALCHEMY_BINDS”的dict上对应数据库的key,我的是“mysqlkey”,其他照旧。

from flask_sqlalchemy import SQLAlchemy
 
db = SQLAlchemy()
 
class MysqlTestTable(db.Model):
    __bind_key__ = "mysqlkey"
    __tablename__ = "test_table"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="PRIMARY"),
        db.Index("idx_unique", "phoneNo"),
    )
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    phoneNo = db.Column(db.BigInteger, nullable=False, comment="")
    name = db.Column(db.String(20), nullable=False, comment="")

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Flask-SQLAlchemy 可以使用 `SQLAlchemy.create_engine()` 方法来连接数据库并访问已有表。在连接数据库时可以使用已有表的 URI(如 'mysql://username:password@host:port/database')并设置 `echo=False` 来禁用调试信息。然后就可以使用 `SQLAlchemy.Table()` 方法指定表名来访问已有表了。 ``` from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@host:port/database' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) existing_table = db.Table('existing_table', db.metadata, autoload=True) ``` 需要注意的是,在使用 `autoload=True` 时,需要先连接数据库,并且需要确保数据库中已经存在这张表。 ### 回答2: 在使用 Flask-SQLAlchemy 连接数据库时,可以通过以下步骤直接连接数据库中已有的表,而不需要重新建表: 1. 首先,在 Flask 的应用程序中导入 FlaskFlask-SQLAlchemy 模块,并创建一个 Flask 应用程序对象。 ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) ``` 2. 然后,配置数据库连接信息。在 Flask 应用程序对象中设置数据库连接字符串,例如使用 SQLite 数据库: ```python app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///your_database.db' ``` 3. 接下来,初始化 SQLAlchemy 对象,并将其与 Flask 应用程序对象关联。 ```python db = SQLAlchemy(app) ``` 4. 创建一个模型类,表示已有的数据库表的结构。在模型类中,定义与数据库表对应的各个字段。 ```python class YourModel(db.Model): __tablename__ = 'your_table_name' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50)) # 定义其他字段... ``` 注意,在模型类中使用 `__tablename__` 属性指定已有的数据库表名称,以便与模型类进行关联。 5. 如果需要,可以在模型类中定义各种操作数据库表的方法,例如查询、插入、更新等。 ```python class YourModel(db.Model): # ... @classmethod def query_all(cls): return cls.query.all() @classmethod def insert_data(cls, data): db.session.add(data) db.session.commit() # ... ``` 6. 最后,在应用程序中可以直接使用已建立的模型类对数据库表进行操作,例如查询数据。 ```python @app.route('/') def index(): data = YourModel.query_all() # 处理数据... return 'Hello, World!' ``` 通过以上方式,可以直接连接数据库中已有的表,而不需要重新建表。需要注意的是,Flask-SQLAlchemy 提供了更多的操作数据库表的方法,可以灵活地满足各种需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值