如何实现Python Flask项目自动识别运行环境,部署时自动切换数据库连接方式
Great question! You don’t have to manually toggle that onServer variable—there are reliable, low-effort ways to auto-detect whether your app is running on PythonAnywhere or locally. Here are two straightforward approaches:
1. Check for PythonAnywhere-Specific Environment Variables
PythonAnywhere sets unique environment variables for every running app. The most reliable one is PYTHONANYWHERE_USER, which holds your account username. We can use this to detect the server environment:
from flask import request, Flask, render_template, send_from_directory, url_for from flask_sqlalchemy import SQLAlchemy import sshtunnel import os # Add this import sshtunnel.SSH_TIMEOUT = 5.0 sshtunnel.TUNNEL_TIMEOUT = 5.0 app = Flask(__name__) app.jinja_env.filters['zip'] = zip app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 1 # Auto-detect if running on PythonAnywhere on_server = 'PYTHONANYWHERE_USER' in os.environ if on_server: app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:password@username.mysql.pythonanywhere-services.com/username$default' else: # SSH to pythonanywhere to get access to database tunnel = sshtunnel.SSHTunnelForwarder( ('ssh.pythonanywhere.com'), ssh_username='username', ssh_password='password', local_bind_address=("127.0.0.1",1000), remote_bind_address=('username.mysql.pythonanywhere-services.com', 3306) ) # Start SSH tunneling tunnel.start() app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:password@127.0.0.1:{}/username$default'.format(tunnel.local_bind_port) db = SQLAlchemy(app)
2. Check the Server Hostname
Another method is to inspect the hostname of the machine running your app. On PythonAnywhere, your server’s hostname will always include pythonanywhere.com:
from flask import request, Flask, render_template, send_from_directory, url_for from flask_sqlalchemy import SQLAlchemy import sshtunnel import socket # Add this import sshtunnel.SSH_TIMEOUT = 5.0 sshtunnel.TUNNEL_TIMEOUT = 5.0 app = Flask(__name__) app.jinja_env.filters['zip'] = zip app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 1 # Auto-detect using hostname hostname = socket.gethostname() on_server = 'pythonanywhere.com' in hostname if on_server: app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:password@username.mysql.pythonanywhere-services.com/username$default' else: # SSH to pythonanywhere to get access to database tunnel = sshtunnel.SSHTunnelForwarder( ('ssh.pythonanywhere.com'), ssh_username='username', ssh_password='password', local_bind_address=("127.0.0.1",1000), remote_bind_address=('username.mysql.pythonanywhere-services.com', 3306) ) # Start SSH tunneling tunnel.start() app.config['SQLALCHEMY_DATABASE_URI']='mysql://username:password@127.0.0.1:{}/username$default'.format(tunnel.local_bind_port) db = SQLAlchemy(app)
Quick Security Note
Hardcoding credentials (like your database and SSH passwords) directly in your code is a bad practice. For better security, store these values in environment variables:
- On PythonAnywhere, you can set them in your app’s "Web" settings under "Environment variables".
- Locally, use a
.envfile with thepython-dotenvpackage to load them intoos.environ.
内容的提问来源于stack exchange,提问作者aldo

