Flask配置MySQL连接信息的最佳实践

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)来管理所有配置项:

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
}

app.py

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连接配置的最佳实践:

config.py

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
}

四、数据库模型定义与使用

配置完成后,可以定义数据模型并使用数据库:

models.py

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}>'

app.py

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:

migrate.py

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

相关推荐
XW01059991 小时前
5-6统计工龄
数据结构·python·算法
酱紫学Java1 小时前
数据安全比赛:Python 内置函数实战指南
后端·python·网络安全
廿一夏1 小时前
数据存储容器
python
SNWCC2 小时前
autodl_M000_pytorch
人工智能·pytorch·python
dreamread2 小时前
Linux下MySQL的简单使用
linux·mysql·adb
deephub2 小时前
多智能体系统的三种编排模式:Supervisor、Pipeline 与 Swarm
人工智能·python·大语言模型·agent
m0_738120722 小时前
渗透测试——pyexpvm靶机详细提权过程(MSF框架,Hydra数据库爆破,SUDO提权)
服务器·网络·数据库·python·sql·web安全
翱翔的苍鹰2 小时前
LangChain是一个主流的大语言模型(LLM)应用开发框架,核心功能是连接大模型与外部资源/工具。
网络·人工智能·python·深度学习·语言模型
rgb2gray2 小时前
论文详解 | HDAM:破解 MAUP 的城市出行需求分析新方法,实现关键驱动精准识别
人工智能·python·llm·大语言模型·需求分析·多模态·maup