?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_migrateapp = 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 SQLAlchemydb = 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 SQLAlchemydb = 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="")