Django如何无需在遗留数据库中建表即可访问其中数据
无需创建新表的Django遗留只读数据库接入方案
核心思路
Django默认会对所有配置的数据库执行迁移检查并尝试创建django_migrations表,通过禁用该库的迁移权限、配置模型为非托管状态,即可完全跳过建表需求,实现只读访问。
具体操作步骤
1. 配置多数据库别名
在settings.py的DATABASES配置项中为遗留数据库添加独立别名,示例:
DATABASES = { 'default': { # 你自己项目的主数据库配置,需要有写入权限用于存储Django自身数据 'ENGINE': 'django.db.backends.mysql', 'NAME': 'your_project_db', 'USER': 'your_user', 'PASSWORD': 'your_pwd', 'HOST': '127.0.0.1', 'PORT': '3306', }, 'legacy_db': { # 遗留数据库配置,使用只读权限的账号 'ENGINE': 'django.db.backends.mysql', 'NAME': 'MyDatabaseName', 'USER': 'readonly_user', 'PASSWORD': 'readonly_pwd', 'HOST': 'legacy_db_host', 'PORT': '3306', } }
2. 编写数据库路由禁止迁移
在项目目录下新建legacy_router.py,实现路由类禁止对遗留库执行任何迁移操作:
class LegacyRouter: def db_for_read(self, model, **hints): # 可选配置:对应遗留库的app所有读请求直接走legacy_db,无需手动指定using if model._meta.app_label == 'legacy': return 'legacy_db' return 'default' def db_for_write(self, model, **hints): # 禁止对遗留库执行写操作,就算代码写错也不会写到遗留库 if model._meta.app_label == 'legacy': raise PermissionError('禁止对遗留数据库执行写操作') return 'default' def allow_relation(self, obj1, obj2, **hints): # 允许跨库关联,按需开启 return True def allow_migrate(self, db, app_label, model_name=None, **hints): # 核心配置:完全禁止对遗留库执行迁移操作,不会尝试创建django_migrations表 if db == 'legacy_db': return False # 主数据库正常执行迁移 return None
在settings.py中注册路由:
DATABASE_ROUTERS = ['your_project_name.legacy_router.LegacyRouter']
3. 自动生成遗留库对应的模型
使用Django内置的inspectdb命令直接从遗留库结构生成ORM模型,无需手动编写:
python manage.py inspectdb --database=legacy_db > legacy/models.py
生成的模型默认会在Meta类中添加managed = False配置,确认该配置存在即可,该参数会告知Django不要对该表执行任何建表、修改表结构、删表的DDL操作:
class LegacyTable(models.Model): id = models.IntegerField(primary_key=True) name = models.CharField(max_length=100) # 其他字段... class Meta: managed = False # 必须保留 db_table = 'your_legacy_table_name'
注意事项
- 自动生成的模型可能存在字段类型映射偏差,首次使用前建议逐个校验字段类型是否和实际表结构一致
- 执行项目迁移时直接运行
python manage.py migrate即可,Django会自动跳过遗留库的所有迁移操作,不会触发建表请求 - 遗留库账号仅保留SELECT权限即可,从数据库层面彻底避免误写风险
内容的提问来源于stack exchange,提问作者RiotF
相关产品推荐
相关产品推荐

