前言
双十一光顾着买东西都没怎么写文章,现在笔记里还有十几篇半成品文章没写完…今天来分享一下 Django 项目切换数据库和迁移数据的方案,网络上找到的文章方法不一,且使用中容易遇到各类报错,本文根据 Django 官方文档和工作中的经验,稳定可靠 , 在博客中长期更新~
如果你遇到同样的问题 , 阅读本文应该能得到比较好的解决方案 。
基本步骤Django 默认使用 SQLite 数据库方便开发,同时其 ORM 支持多种数据库,只要安装对应的驱动就行 。
切换数据库一般是将开发环境的 SQLite 切换到 MySQL (MariaDB) 或 PostgreSql ,本文只测试了从 SQLite 到 MySQL / PostgreSQL,同理,其他切换路径也是可以的 。
数据库的表结构没啥问题,使用 Django 的 migrate 功能就行了
关键在于数据迁移,可以使用 Navicat 之类的数据库工具进行数据同步,但往往会因为表之间的约束关系导致同步失败(要求按特定顺序导入数据) 。
所以最好的方法是使用 Django 的
dumpdata
功能,将数据库导出为 json 或 xml 文件,然后切换数据库再导入 。步骤如下:
- 导出原有数据:
python manage.py dumpdata -o db.json
- 在目标数据库(MySQL / PostgreSql)里创建一个空的库
- 在
settings.py
里切换到新的数据库 - 建立新的数据库表结构
python manage.py migrate
- 导入原有数据:
python manage.py loaddata db.json
附上几种数据库配置,方便使用
db_config = {'sqlite': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),'OPTIONS': {'timeout': 20,}},'pgsql': {'ENGINE': 'django.db.backends.postgresql','NAME': '数据库名称','USER': '用户名','PASSWORD': '密码','HOST': '数据库服务器地址','PORT': 5432,},'mysql': {'ENGINE': 'django.db.backends.mysql','NAME': '数据库名称','USER': '用户名','PASSWORD': '密码','HOST': '数据库服务器地址','PORT': 3306,}}# 这里可以方便切换不同数据库DATABASES = {'default': db_config['pgsql']}
其中:- MySQL 需要安装
mysqlclient
包 - PostgreSql 需要安装
psycopg2
包
导出报错报错信息
CommandError: Unable to serialize database: 'gbk' codec can't encode character '\u30fb' in position 4: illegal multibyte sequence
原因跟编码有关解决方法使用 Python 的 UTF-8 模式导出数据就没问题
用这个命令导出文件
(不导出
auth.permission
和 contenttypes
, 这俩在 migrate
时会自动生成,这样避免了导入原有数据时冲突)python -Xutf8 manage.py dumpdata --exclude auth.permission --exclude contenttypes > db.json
或者python -Xutf8 manage.py dumpdata -o db.json
导入过程出错解决报错1: Duplicate entry报错信息django.db.utils.IntegrityError: Problem installing fixture 'db.json'Could not load contenttypes.ContentType(pk=15): (1062, "Duplicate entry 'xxx' for key 'django_content_type.django_content_type_app_label_model_76bd3d3b_uniq'")
解决方法一: 重新导出数据加上这俩参数--natural-primary
: Omits the primary key in the serialized data of this object since it can be calculated during deserialization.--natural-foreign
: Uses the natural_key() model method to serialize any foreign key and many-to-many relationship to objects of the type that defines the method.
python3 manage.py dumpdata --natural-primary --natural-foreign -o db.json
解决方法二: 删除 content_type
数据另一种思路,把 migrate
过程产生的初始化数据删了,避免导入时和原有数据冲突先进入 python shell
python3 manage.py shell
输入以下Python代码执行from django.contrib.contenttypes.models import ContentTypeContentType.objects.all().delete()
报错2: 编码错误报错信息UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xff in position 0: invalid start byte in Django
解决方法一: 使用 Python 的 UTF8 模式(推荐)在导入命令前面加上 -Xutf8
参数python -Xutf8 manage.py loaddata db.json
解决方案二: 魔改 Django 代码能用 , 但不推荐,实在没办法再来试这个方法推荐阅读
- MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选
- Django的简单使用
- rabbitmq docker安装消息队列及数据库(mongo、mysql)
- 如何更换彩铃铃声(6元彩铃怎么退订)
- 无期迷途监管对象怎么更换
- django-environ学习
- Redis先操作数据库和先删除缓存, 一致性分析
- 时序数据库TDengine详细安装+集成流程+问题解决
- 云数据库时代,DBA将走向何方?
- 我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang