Flask连接MySQL的配置信息写在配置文件中的方法和最佳实践
在Flask项目中,将MySQL数据库连接信息写入配置文件是一种重要的工程实践,能够提高代码的可维护性、安全性和灵活性。下面详细介绍配置方法、不同配置方式的对比以及最佳实践。
一、配置MySQL连接信息的基本方法
1.1 直接在Flask应用中进行配置
最基本的配置方式是在Flask应用实例中直接设置数据库连接URI:
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 直接配置MySQL连接信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@localhost:3306/dbname'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
这种方式简单直接,但存在安全隐患,因为数据库密码等敏感信息直接暴露在代码中。
1.2 使用环境变量配置
为了避免敏感信息泄露,推荐使用环境变量来配置数据库连接信息:
python
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 从环境变量读取配置
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'mysql+pymysql://username:password@localhost:3306/dbname')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
在系统环境中设置环境变量:
bash
export DATABASE_URL="mysql+pymysql://username:password@localhost:3306/dbname"
这种方式提高了安全性,敏感信息不会直接出现在代码版本控制中。
1.3 使用独立的配置文件
创建专门的配置文件(如config.py)来管理所有配置项:
python
import os
class Config:
"""基础配置类"""
SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard-to-guess-string'
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
"""开发环境配置"""
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
'mysql+pymysql://dev_user:dev_password@localhost:3306/dev_db'
class ProductionConfig(Config):
"""生产环境配置"""
DEBUG = False
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'mysql+pymysql://prod_user:prod_password@localhost:3306/prod_db'
class TestingConfig(Config):
"""测试环境配置"""
TESTING = True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'mysql+pymysql://test_user:test_password@localhost:3306/test_db'
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'default': DevelopmentConfig
}
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config
db = SQLAlchemy()
def create_app(config_name='default'):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
return app
这种方式支持多环境配置,便于在不同部署环境中切换。
二、不同配置方式的对比分析
| 配置方式 | 安全性 | 维护性 | 灵活性 | 适用场景 |
|---|---|---|---|---|
| 直接配置 | 低 | 低 | 低 | 快速原型、学习演示 |
| 环境变量 | 高 | 中 | 中 | 生产环境、容器化部署 |
| 配置文件 | 中 | 高 | 高 | 复杂项目、多环境部署 |
三、完整的配置文件示例
下面是一个完整的Flask项目配置文件示例,展示了MySQL连接配置的最佳实践:
python
import os
from datetime import timedelta
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
"""基础配置类"""
# 安全配置
SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key-here'
# 数据库基础配置
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = False # 是否打印SQL语句,开发时可设为True
# 会话配置
PERMANENT_SESSION_LIFETIME = timedelta(days=7)
# 文件上传配置
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB
UPLOAD_FOLDER = os.path.join(basedir, 'uploads')
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
"""开发环境配置"""
DEBUG = True
# MySQL连接配置
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
'mysql+pymysql://dev_user:password@localhost:3306/flask_dev'
# 开发环境下显示SQL语句
SQLALCHEMY_ECHO = True
class ProductionConfig(Config):
"""生产环境配置"""
DEBUG = False
# 生产环境必须使用环境变量
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
@classmethod
def init_app(cls, app):
Config.init_app(app)
# 生产环境日志配置
import logging
from logging.handlers import RotatingFileHandler
# 文件日志处理器
file_handler = RotatingFileHandler(
'logs/flask_app.log',
maxBytes=10485760, # 10MB
backupCount=10
)
file_handler.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
)
file_handler.setFormatter(formatter)
app.logger.addHandler(file_handler)
class TestingConfig(Config):
"""测试环境配置"""
TESTING = True
# 测试数据库配置
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'mysql+pymysql://test_user:password@localhost:3306/flask_test'
# 测试时禁用CSRF保护
WTF_CSRF_ENABLED = False
# 配置字典
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'default': DevelopmentConfig
}
四、数据库模型定义与使用
配置完成后,可以定义数据模型并使用数据库:
python
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
"""用户模型"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True, nullable=False)
email = db.Column(db.String(120), unique=True, index=True, nullable=False)
password_hash = db.Column(db.String(128))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f'<User {self.username}>'
class Post(db.Model):
"""文章模型"""
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(140), nullable=False)
content = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 关系定义
author = db.relationship('User', backref=db.backref('posts', lazy='dynamic'))
def __repr__(self):
return f'<Post {self.title}>'
python
from flask import Flask
from config import config
from models import db
def create_app(config_name='default'):
app = Flask(__name__)
# 加载配置
app.config.from_object(config[config_name])
config[config_name].init_app(app)
# 初始化扩展
db.init_app(app)
# 注册蓝图
from auth import auth_bp
from main import main_bp
app.register_blueprint(auth_bp)
app.register_blueprint(main_bp)
return app
# 应用工厂的使用
app = create_app('development')
@app.shell_context_processor
def make_shell_context():
"""为Flask shell添加上下文"""
return {'db': db, 'User': User, 'Post': Post}
if __name__ == '__main__':
app.run()
五、数据库迁移配置
对于生产环境,数据库迁移是必不可少的。配置Flask-Migrate:
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import config
db = SQLAlchemy()
migrate = Migrate()
def create_app(config_name='default'):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
migrate.init_app(app, db)
return app
使用迁移命令:
bash
# 初始化迁移仓库
flask db init
# 生成迁移脚本
flask db migrate -m "Initial migration"
# 应用迁移
flask db upgrade
六、最佳实践总结
1