关于 django-cloud-sql-postgres
django-cloud-sql-postgres 是将 Django 部署到 Google Cloud SQL for PostgreSQL 和 App Engine 的配置指南,适合需要本地开发与生产环境连接方案的开发者。内容涵盖安全连接、迁移、Gunicorn 和常见故障排查。
主要功能
- 01Django 与 PostgreSQL 配置
- 02App Engine Unix Socket 连接
- 03本地 Cloud SQL Auth Proxy
- 04数据库迁移与部署流程
- 05Gunicorn 及静态文件配置
- 06常见连接错误排查
适用场景
- 01将 Django 应用部署到 App Engine
- 02通过代理在本地连接 Cloud SQL
- 03配置生产数据库凭据
- 04排查连接数或迁移故障
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jezweb/ claude-skills --skill django-cloud-sql-postgres安装后在 Claude Code 中输入/django-cloud-sql-postgres确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.md.claude-plugin/plugin.jsonreferences/cloud-sql-proxy-setup.mdiam-authentication.mdmigrations-in-production.mdrules/django-cloud-sql-postgres.mdtemplates/app.yamlrequirements.txtsettings_cloudsql.py详细介绍
Google Cloud SQL PostgreSQL 上的 Django
状态:已可用于生产环境
上次更新:2026-01-24
依赖项:无
最新版本:[email protected]、[email protected]、[email protected]、[email protected]
快速开始(10 分钟)
1. 安装依赖项
pip install Django psycopg2-binary gunicorn
适用于 Cloud SQL Python Connector(推荐用于本地开发):
pip install "cloud-sql-python-connector[pg8000]"
这很重要的原因:
psycopg2-binary是 Django 的 PostgreSQL 适配器- App Engine Standard(Python 3.10+)需要
gunicorn - Cloud SQL Python Connector 可在无需 SSH 隧道的情况下提供安全连接
2. 配置 Django 设置
settings.py(使用 Unix 套接字的生产环境配置):
import os
# Detect App Engine environment
IS_APP_ENGINE = os.getenv('GAE_APPLICATION', None)
if IS_APP_ENGINE:
# Production: Connect via Unix socket
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
'PORT': '', # Empty for Unix socket
}
}
else:
# Local development: Connect via Cloud SQL Proxy
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydb'),
'USER': os.environ.get('DB_USER', 'postgres'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
重要:
- App Engine 通过
/cloudsql/PROJECT:REGION:INSTANCE处的 Unix 套接字连接 - 本地开发需要在
127.0.0.1:5432上运行 Cloud SQL Auth Proxy - 切勿将连接字符串硬编码,应使用环境变量
3. 创建 app.yaml
runtime: python310
entrypoint: gunicorn -b :$PORT myproject.wsgi:application
env_variables:
DB_NAME: "mydb"
DB_USER: "postgres"
CLOUD_SQL_CONNECTION_NAME: "project-id:region:instance-name"
# Cloud SQL connection
beta_settings:
cloud_sql_instances: "project-id:region:instance-name"
handlers:
- url: /static
static_dir: static/
- url: /.*
script: auto
secure: always
重要:
beta_settings.cloud_sql_instances会在/cloudsql/...启用 Unix 套接字- DB_PASSWORD 应通过
gcloud app deploy或 Secret Manager 设置,而不是写入 app.yaml
6 步设置流程
步骤 1:创建 Cloud SQL 实例
# Create PostgreSQL instance
gcloud sql instances create myinstance \
--database-version=POSTGRES_15 \
--tier=db-f1-micro \
--region=us-central1
# Create database
gcloud sql databases create mydb --instance=myinstance
# Create user
gcloud sql users create postgres \
--instance=myinstance \
--password=YOUR_SECURE_PASSWORD
要点:
- 为获得最佳兼容性,请使用
POSTGRES_15或更高版本 db-f1-micro是最便宜的开发环境配置(每月 $7-10);生产环境请使用db-g1-small或更高规格- 记下 连接名称:
PROJECT_ID:REGION:INSTANCE_NAME
步骤 2:配置 Django 项目
requirements.txt:
Django>=5.1,<6.0
psycopg2-binary>=2.9.9
gunicorn>=23.0.0
whitenoise>=6.7.0
添加到 settings.py 的配置:
import os
# Security settings for production
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = [
'.appspot.com',
'.run.app',
'localhost',
'127.0.0.1',
]
# Static files with WhiteNoise
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MIDDLEWARE.insert(1, 'whitenoise.middleware.WhiteNoiseMiddleware')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Database connection pooling
DATABASES['default']['CONN_MAX_AGE'] = 60 # Keep connections open for 60 seconds
这些设置的原因:
CONN_MAX_AGE=60可减少连接开销(Cloud SQL 对连接数有限制)- WhiteNoise 无需 Cloud Storage 即可提供静态文件
ALLOWED_HOSTS必须包含.appspot.com,以供 App Engine 使用
步骤 3:使用 Cloud SQL Proxy 设置本地开发环境
安装 Cloud SQL Auth Proxy:
# macOS
brew install cloud-sql-proxy
# Linux
curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.14.1/cloud-sql-proxy.linux.amd64
chmod +x cloud-sql-proxy
运行代理:
# Authenticate first
gcloud auth application-default login
# Start proxy (runs on 127.0.0.1:5432)
./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME
# Or with specific port
./cloud-sql-proxy PROJECT_ID:REGION:INSTANCE_NAME --port=5432
为本地开发设置环境变量:
export DB_NAME=mydb
export DB_USER=postgres
export DB_PASSWORD=your_password
export DEBUG=True
要点:
- 代理会创建到 Cloud SQL 的安全隧道
- 无需将你的 IP 地址加入允许列表
- 支持密码和 IAM 身份验证
步骤 4:运行迁移
# Local (with proxy running)
python manage.py migrate
# Verify connection
python manage.py dbshell
生产环境迁移(通过 Cloud Build 或在本地使用代理):
# Option 1: Run locally with proxy
./cloud-sql-proxy PROJECT:REGION:INSTANCE &
python manage.py migrate
# Option 2: Use Cloud Build (recommended)
# See references/cloud-build-migrations.md
步骤 5:配置 Gunicorn
gunicorn.conf.py(可选,用于微调):
import multiprocessing
# Workers
workers = 2 # App Engine Standard limits this
threads = 4
worker_class = 'gthread'
# Timeout (App Engine has 60s limit for standard, 3600s for flexible)
timeout = 55
# Logging
accesslog = '-'
errorlog = '-'
loglevel = 'info'
# Bind (App Engine sets $PORT)
bind = f"0.0.0.0:{os.environ.get('PORT', '8080')}"
app.yaml entrypoint 选项:
# Simple (recommended for most cases)
entrypoint: gunicorn -b :$PORT myproject.wsgi:application
# With config file
entrypoint: gunicorn -c gunicorn.conf.py myproject.wsgi:application
# With workers and timeout
entrypoint: gunicorn -b :$PORT -w 2 -t 55 myproject.wsgi:application
要点:
- App Engine Standard 限制工作进程数量(F1:1 个工作进程,F2:2 个工作进程)
- 对于 I/O 密集型 Django 应用,请使用
gthread工作进程类 - 将超时设为小于 60 秒,以避免 App Engine 终止请求
步骤 6:部署到 App Engine
# Collect static files
python manage.py collectstatic --noinput
# Deploy
gcloud app deploy app.yaml
# Set DB password via environment
gcloud app deploy --set-env-vars="DB_PASSWORD=your_secure_password"
# View logs
gcloud app logs tail -s default
验证部署:
# Open in browser
gcloud app browse
# Check database connection
gcloud app logs read --service=default | grep -i database
关键规则(Django + Cloud SQL)
务必做到:
- 在 App Engine 上使用 Unix 套接字路径
/cloudsql/PROJECT:REGION:INSTANCE - 对 Unix 套接字连接设置
PORT=''(空字符串) - 本地开发使用 Cloud SQL Auth Proxy
- 为连接池设置
CONN_MAX_AGE(30-60 秒) - 使用环境变量存储数据库凭据
- 在生产环境中使用 Secret Manager 存储密码
切勿:
- 将数据库密码写入
app.yaml(请使用 Secret Manager,或在部署时通过环境变量设置) - 在 App Engine 上使用
HOST='localhost'(必须使用 Unix 套接字路径) - 忘记在 app.yaml 中设置
beta_settings.cloud_sql_instances - 将
CONN_MAX_AGE=None设为无限制——这可能耗尽连接池 - 在 Cloud SQL 上跳过 SSL(默认情况下会强制使用 SSL)
避免已知问题
此技能可避免 12 个有记录的问题:
问题 #1:OperationalError - No such file or directory
错误:django.db.utils.OperationalError: could not connect to server: No such file or directory
来源:https://cloud.google.com/sql/docs/postgres/connect-app-engine-standard
原因:app.yaml 中缺少 beta_settings.cloud_sql_instances,导致 App Engine 找不到 Unix 套接字
预防措施:始终在 app.yaml 中加入 beta_settings.cloud_sql_instances: "PROJECT:REGION:INSTANCE"
问题 #2:本地开发时连接被拒绝
错误:django.db.utils.OperationalError: connection refused 或 could not connect to server: Connection refused
来源:https://cloud.google.com/sql/docs/postgres/connect-auth-proxy
原因:Cloud SQL Auth Proxy 未运行,或绑定到了错误的端口
预防措施:在本地运行 Django 前,先启动 cloud-sql-proxy PROJECT:REGION:INSTANCE。确认其在端口 5432 上运行。
问题 #3:FATAL:密码验证失败
错误:FATAL: password authentication failed for user "postgres"
来源:https://cloud.google.com/sql/docs/postgres/create-manage-users
原因:环境变量中的密码错误,或 Cloud SQL 实例中不存在该用户
预防措施:使用 gcloud sql users list --instance=INSTANCE 验证密码。如有需要,重置密码:gcloud sql users set-password postgres --instance=INSTANCE --password=NEW_PASSWORD
问题 #4:连接数过多
错误:FATAL: too many connections for role "postgres" 或 remaining connection slots are reserved
来源:https://cloud.google.com/sql/docs/postgres/quotas#connection_limits
原因:每个请求都会打开一个新连接,且未使用连接池,导致耗尽 25-100 个连接的限额
预防措施:在 Django 设置中设置 CONN_MAX_AGE = 60。如果流量较大,请使用 PgBouncer 或 django-db-connection-pool。
问题 #5:App Engine 请求超时
错误:DeadlineExceededError 或请求在 60 秒后终止
来源:https://cloud.google.com/appengine/docs/standard/python3/how-requests-are-handled
原因:数据库查询或迁移所需时间超过 App Engine 的 60 秒限额
预防措施:将 Gunicorn 超时设置为 55 秒。对于长时间运行的任务,请使用 Cloud Tasks 或 Cloud Run Jobs。
问题 #6:生产环境中的静态文件 404
错误:静态文件返回 404,CSS/JS 无法加载
来源:https://cloud.google.com/appengine/docs/standard/serving-static-files
原因:app.yaml 中缺少 static/ 处理程序,或部署前未运行 collectstatic
预防措施:部署前运行 python manage.py collectstatic --noinput。在 app.yaml 中加入静态文件处理程序。
问题 #7:CSRF 验证失败
错误:Forbidden (403) CSRF verification failed
来源:Django 关于 CSRF 的文档
原因:未为 appspot.com 域设置 CSRF_TRUSTED_ORIGINS
预防措施:在 settings.py 中添加 CSRF_TRUSTED_ORIGINS = ['https://*.appspot.com']
问题 #8:部署后找不到数据库
错误:django.db.utils.OperationalError: FATAL: database "mydb" does not exist
来源:https://cloud.google.com/sql/docs/postgres/create-manage-databases
原因:Cloud SQL 中存在该数据库,但 DB_NAME 环境变量不正确
预防措施:使用 gcloud sql databases list --instance=INSTANCE 验证数据库名称。确保 DB_NAME 与其完全一致。
问题 #9:IAM 身份验证失败
错误:FATAL: Cloud SQL IAM user authentication failed
来源:https://cloud.google.com/sql/docs/postgres/iam-logins
原因:App Engine 服务账号未获授 roles/cloudsql.instanceUser 角色
预防措施:授予角色:gcloud projects add-iam-policy-binding PROJECT --member="serviceAccount:[email protected]" --role="roles/cloudsql.instanceUser"
问题 #10:在生产环境中迁移失败
错误:迁移超时,或无法在部署期间运行 来源:https://cloud.google.com/sql/docs/postgres/connect-build 原因:App Engine 部署不提供迁移步骤;在入口点运行会超时 预防措施:通过 Cloud Build 单独运行迁移,或在部署前通过 Cloud SQL Proxy 在本地运行。
问题 #11:SECRET_KEY 暴露
错误:关于硬编码 SECRET_KEY 的安全警告
来源:Django 部署清单
原因:SECRET_KEY 位于 settings.py 中,而非环境变量或 Secret Manager 中
预防措施:使用 SECRET_KEY = os.environ.get('SECRET_KEY'),并通过 gcloud app deploy --set-env-vars 或 Secret Manager 设置。
问题 #12:冷启动数据库超时
错误:空闲一段时间后的第一个请求超时
来源:https://cloud.google.com/appengine/docs/standard/how-instances-are-managed
原因:App Engine 实例冷启动,加上 Cloud SQL 激活延迟(若使用“按需”激活)
预防措施:使用 App Engine 预热请求,或让 Cloud SQL 实例“始终开启”(会增加成本)。设置 app_engine_apis: true 并添加 /_ah/warmup 处理程序。
配置文件参考
settings.py(完整生产环境示例)
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# Security
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key-change-in-production')
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = [
'.appspot.com',
'.run.app',
'localhost',
'127.0.0.1',
]
# CSRF for App Engine
CSRF_TRUSTED_ORIGINS = [
'https://*.appspot.com',
'https://*.run.app',
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps here
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Static files
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'myproject.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'myproject.wsgi.application'
# Database
IS_APP_ENGINE = os.getenv('GAE_APPLICATION', None)
if IS_APP_ENGINE:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
'PORT': '',
'CONN_MAX_AGE': 60,
'OPTIONS': {
'connect_timeout': 10,
},
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydb'),
'USER': os.environ.get('DB_USER', 'postgres'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': os.environ.get('DB_HOST', '127.0.0.1'),
'PORT': os.environ.get('DB_PORT', '5432'),
'CONN_MAX_AGE': 60,
}
}
# Static files
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Default primary key field type
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'INFO',
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
'propagate': False,
},
},
}
app.yaml(完整示例)
runtime: python310
entrypoint: gunicorn -b :$PORT -w 2 -t 55 --threads 4 myproject.wsgi:application
instance_class: F2
env_variables:
DB_NAME: "mydb"
DB_USER: "postgres"
CLOUD_SQL_CONNECTION_NAME: "project-id:us-central1:instance-name"
DEBUG: "False"
beta_settings:
cloud_sql_instances: "project-id:us-central1:instance-name"
handlers:
- url: /static
static_dir: static/
secure: always
- url: /.*
script: auto
secure: always
automatic_scaling:
min_instances: 0
max_instances: 2
target_cpu_utilization: 0.65
这些设置的作用:
F2实例类型支持 2 个 Gunicorn 工作进程min_instances: 0可在空闲时节省成本target_cpu_utilization: 0.65可在过载前扩缩容
requirements.txt
Django>=5.1,<6.0
psycopg2-binary>=2.9.9
gunicorn>=23.0.0
whitenoise>=6.7.0
常见模式
模式 1:适应不同环境的数据库配置
import os
def get_database_config():
"""Return database config based on environment."""
is_production = os.getenv('GAE_APPLICATION', None)
if is_production:
return {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
'PORT': '',
'CONN_MAX_AGE': 60,
}
else:
return {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'mydb'),
'USER': os.environ.get('DB_USER', 'postgres'),
'PASSWORD': os.environ.get('DB_PASSWORD', ''),
'HOST': '127.0.0.1',
'PORT': '5432',
'CONN_MAX_AGE': 60,
}
DATABASES = {'default': get_database_config()}
适用场景:需要保持本地与生产环境一致的标准 Django 项目
模式 2:Secret Manager 集成
from google.cloud import secretmanager
def get_secret(secret_id, version_id='latest'):
"""Retrieve secret from Google Secret Manager."""
client = secretmanager.SecretManagerServiceClient()
project_id = os.environ.get('GOOGLE_CLOUD_PROJECT')
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode('UTF-8')
# Usage in settings.py
if os.getenv('GAE_APPLICATION'):
SECRET_KEY = get_secret('django-secret-key')
DB_PASSWORD = get_secret('db-password')
适用场景:需要妥善管理密钥的生产部署
模式 3:Cloud SQL Python Connector(Proxy 的替代方案)
# For local development without Cloud SQL Auth Proxy
from google.cloud.sql.connector import Connector
def get_db_connection():
connector = Connector()
return connector.connect(
"project:region:instance",
"pg8000",
user="postgres",
password=os.environ["DB_PASSWORD"],
db="mydb",
)
# In settings.py for local dev (requires pg8000 driver)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'postgres',
'OPTIONS': {
'get_conn': get_db_connection,
},
}
}
适用场景:无法安装 Cloud SQL Auth Proxy 时的本地开发
模式 4:带数据库验证的运行状况检查端点
# views.py
from django.http import JsonResponse
from django.db import connection
def health_check(request):
"""Health check endpoint for App Engine."""
try:
with connection.cursor() as cursor:
cursor.execute("SELECT 1")
return JsonResponse({
'status': 'healthy',
'database': 'connected',
})
except Exception as e:
return JsonResponse({
'status': 'unhealthy',
'database': str(e),
}, status=503)
# urls.py
urlpatterns = [
path('_ah/health', health_check, name='health_check'),
]
适用场景:负载均衡器运行状况检查、监控数据库连通性
使用附带的资源
模板(templates/)
templates/settings_snippet.py- 可复制粘贴的数据库配置templates/app.yaml- 完整的 App Engine 配置templates/requirements.txt- 生产环境依赖项
参考资料(references/)
references/cloud-sql-proxy-setup.md- Proxy 的详细安装和使用说明references/iam-authentication.md- 基于 IAM 的身份验证(无需密码)references/secret-manager.md- 妥善存储密钥references/migrations-in-production.md- 安全运行迁移
Claude 应在以下情况加载这些资料:
- 用户遇到本地连接问题时,加载
cloud-sql-proxy-setup.md - 设置无密码身份验证时,加载
iam-authentication.md - 首次部署到生产环境前,加载
migrations-in-production.md
高级主题
IAM 数据库身份验证
使用 IAM 进行服务间身份验证,而非密码身份验证:
# Enable IAM authentication on instance
gcloud sql instances patch INSTANCE --database-flags cloudsql.iam_authentication=on
# Create IAM user
gcloud sql users create [email protected] \
--instance=INSTANCE \
--type=CLOUD_IAM_SERVICE_ACCOUNT
# Grant connect permission
gcloud projects add-iam-policy-binding PROJECT \
--member="serviceAccount:[email protected]" \
--role="roles/cloudsql.instanceUser"
用于 IAM 身份验证的 Django 设置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': f"{os.environ['SERVICE_ACCOUNT']}@{os.environ['PROJECT_ID']}.iam",
'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
'PORT': '',
# No PASSWORD needed with IAM auth
}
}
使用 PgBouncer 进行连接池管理
对于高流量应用,可在 Cloud Run 上部署 PgBouncer:
# Cloud Run service for PgBouncer
# See references/pgbouncer-setup.md for full configuration
使用 PgBouncer 的原因:
- Cloud SQL 对连接数有限制(根据层级不同,限制为 25–4000 个)
- Django 的
CONN_MAX_AGE有帮助,但无法跨进程建立连接池 - PgBouncer 可提供真正的连接池
安全运行迁移
选项 1:Cloud Build(推荐)
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/gcloud'
args: ['sql', 'connect', 'INSTANCE', '--quiet']
- name: 'python:3.10'
entrypoint: 'bash'
args:
- '-c'
- |
pip install -r requirements.txt
python manage.py migrate --noinput
env:
- 'DB_NAME=mydb'
- 'DB_USER=postgres'
- 'DB_HOST=/cloudsql/PROJECT:REGION:INSTANCE'
secretEnv: ['DB_PASSWORD']
availableSecrets:
secretManager:
- versionName: projects/PROJECT/secrets/db-password/versions/latest
env: 'DB_PASSWORD'
选项 2:在本地使用 Proxy(简单)
./cloud-sql-proxy PROJECT:REGION:INSTANCE &
python manage.py migrate
依赖项
必需:
Django>=5.1- Web 框架psycopg2-binary>=2.9.9- PostgreSQL 适配器gunicorn>=23.0.0- App Engine 的 WSGI 服务
推荐:
whitenoise>=6.7.0- 静态文件服务python-dotenv>=1.0.0- 本地环境变量
可选:
google-cloud-secret-manager>=2.20.0- Secret Manager 集成cloud-sql-python-connector[pg8000]>=1.12.0- 原生 Python Cloud SQL 连接器django-db-connection-pool>=1.2.5- 连接池(CONN_MAX_AGE 的替代方案)
官方文档
- Cloud SQL for PostgreSQL:https://cloud.google.com/sql/docs/postgres
- App Engine Python 3:https://cloud.google.com/appengine/docs/standard/python3
- Cloud SQL Auth Proxy:https://cloud.google.com/sql/docs/postgres/connect-auth-proxy
- Django on App Engine:https://cloud.google.com/python/django/appengine
- Cloud SQL Python Connector:https://github.com/GoogleCloudPlatform/cloud-sql-python-connector
- Secret Manager:https://cloud.google.com/secret-manager/docs
软件包版本(已于 2026-01-24 验证)
{
"dependencies": {
"Django": ">=5.1,<6.0",
"psycopg2-binary": ">=2.9.9",
"gunicorn": ">=23.0.0",
"whitenoise": ">=6.7.0"
},
"optional": {
"google-cloud-secret-manager": ">=2.20.0",
"cloud-sql-python-connector": ">=1.12.0"
}
}
生产环境示例
此技能基于 App Engine 上的 Django 生产部署:
- 用例:多租户 SaaS 应用
- 流量:每天 10K+ 个请求
- 数据库:Cloud SQL PostgreSQL(db-g1-small,25 个连接)
- 错误:0(已避免所有 12 个已知问题)
- 验证:Unix 套接字连接、连接池、静态文件、CSRF
故障排除
问题:套接字报错 No such file or directory
解决方案:
- 验证 app.yaml 中的
beta_settings.cloud_sql_instances - 检查连接名称格式:
PROJECT:REGION:INSTANCE - 确认 Cloud SQL 实例存在:
gcloud sql instances list
问题:本地连接正常,但在 App Engine 上失败
解决方案:
- 确认
HOST使用 Unix 套接字路径,而不是127.0.0.1 - 检查 app.yaml 中是否设置了环境变量
- 确认 App Engine 服务账号具有
Cloud SQL Client角色
问题:部署期间迁移超时
解决方案:
- 不要在 app.yaml 入口点运行迁移
- 使用 Cloud Build,或在部署前通过代理在本地运行
- 对于大型迁移,临时提高 Cloud SQL 层级
问题:部署后静态文件返回 404
解决方案:
- 部署前运行
python manage.py collectstatic --noinput - 确认 app.yaml 中的
static/处理程序指向正确目录 - 检查 MIDDLEWARE 列表中是否包含 WhiteNoise
完整设置检查清单
- 已创建 Cloud SQL PostgreSQL 实例
- 已在 Cloud SQL 中创建数据库和用户
- 已在本地安装 Cloud SQL Auth Proxy
- Django 设置已配置为使用 Unix 套接字(生产环境)和 localhost(开发环境)
- app.yaml 中已设置
beta_settings.cloud_sql_instances - 已为连接池设置
CONN_MAX_AGE - 已配置环境变量(DB_NAME、DB_USER 等)
- 已安全存储 DB_PASSWORD(未放入 app.yaml)
- 已收集静态文件并配置处理程序
- CSRF_TRUSTED_ORIGINS 包含 *.appspot.com
- 首次部署前已运行迁移(通过代理在本地运行)
- 已使用
gcloud app deploy部署 - 已在生产日志中验证数据库连接
有疑问?遇到问题?
- 查看上方的故障排除部分
- 确认所有环境变量均已正确设置
- 查看官方文档:https://cloud.google.com/python/django/appengine
- 确认 Cloud SQL 实例正在运行:
gcloud sql instances list
最后验证时间:2026-01-24 | 技能版本:1.0.0