同一Ubuntu服务器下多Django项目共用Word模型数据库方案咨询
方案实现指导与优化建议
一、共用数据库存储Word模型完全可行,且能大幅提升迁移效率
1. 替换SQLite为客户端-服务器型数据库(推荐PostgreSQL/MySQL)
SQLite是文件型数据库,多进程并发写入易出现锁表、性能瓶颈,百万级数据高频操作场景下不适合共享。建议换成PostgreSQL:
- 安装PostgreSQL:
sudo apt update && sudo apt install postgresql postgresql-contrib - 创建共用数据库与授权用户:
执行sudo -u postgres psql进入命令行,依次运行:CREATE DATABASE db_word; CREATE USER django_word WITH PASSWORD 'your_secure_password'; GRANT ALL PRIVILEGES ON DATABASE db_word TO django_word;
2. 配置多数据库与路由
在三个Django项目的settings.py中添加共用数据库配置,并通过路由指定Word模型使用共用库:
- 修改
DATABASES配置:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', }, 'shared_word_db': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'db_word', 'USER': 'django_word', 'PASSWORD': 'your_secure_password', 'HOST': 'localhost', 'PORT': '5432', } } - 编写数据库路由文件(如
yourapp/router.py):class WordDBRouter: def db_for_read(self, model, **hints): if model._meta.app_label == 'word_app' and model.__name__ == 'Word': return 'shared_word_db' return 'default' def db_for_write(self, model, **hints): if model._meta.app_label == 'word_app' and model.__name__ == 'Word': return 'shared_word_db' return 'default' def allow_relation(self, obj1, obj2, **hints): if obj1._meta.app_label == 'word_app' or obj2._meta.app_label == 'word_app': return True return None def allow_migrate(self, db, app_label, model_name=None, **hints): if app_label == 'word_app' and model_name == 'word': return db == 'shared_word_db' return db == 'default' - 在
settings.py中注册路由:DATABASE_ROUTERS = ['yourapp.router.WordDBRouter']
3. 统一Word模型并迁移数据
- 定义统一的Word模型(在任意项目中编写后同步到另外两个项目):
from django.db import models class Word(models.Model): # 原有字段示例 image = models.ImageField(upload_to='word_images/') content = models.CharField(max_length=255) # 新增归属字段 PROJECT_CHOICES = [('D1', 'D1'), ('D2', 'D2'), ('D3', 'D3')] belongs_to = models.CharField(max_length=2, choices=PROJECT_CHOICES, db_index=True) class Meta: app_label = 'word_app' - 创建共用库表结构:
python manage.py makemigrations word_app python manage.py migrate word_app --database=shared_word_db - 批量迁移原有数据:编写脚本将每个项目本地Word数据导入共用库,指定对应
belongs_to值:
分别在D1、D2、D3中运行,传入from word_app.models import Word as LocalWord from word_app.models import Word as SharedWord def migrate_local_words(project_tag): # 分批次读取避免内存溢出 for local_word in LocalWord.objects.all().iterator(chunk_size=1000): SharedWord.objects.create( image=local_word.image, content=local_word.content, belongs_to=project_tag )'D1'、'D2'、'D3'作为参数。
4. 实现高效迁移逻辑
直接通过批量更新belongs_to字段完成迁移,无需导出导入:
from word_app.models import Word def transfer_words(from_project, to_project, word_ids): # 批量更新,效率远高于逐条操作 Word.objects.filter(id__in=word_ids, belongs_to=from_project).update(belongs_to=to_project)
二、其他优化建议
- 图片存储优化:不要将图片二进制数据存入数据库,改用统一的文件目录或MinIO等对象存储,数据库仅存储图片路径,避免迁移时处理大文件。
- 异步处理:百万级数据迁移用Celery异步执行,分批次处理,避免阻塞Web服务。
- 索引优化:为Word模型的常用查询字段(如
content、belongs_to)添加索引,提升查询与更新效率。 - SQLite共享备选(不推荐):若坚持用SQLite,需确保共用数据库文件权限为三个项目进程可读写,且在每个项目的数据库连接中设置
PRAGMA busy_timeout=5000;,但高频写入场景下仍会出现锁表问题。
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

