Django更换数据库和迁移数据方案
前言
双十一光顾着买东西都没怎么写文章,现在笔记里还有十几篇半成品文章没写完…
今天来分享一下 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 ContentType
ContentType.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 代码
能用,但不推荐,实在没办法再来试这个方法
修改文件
lib\site-packages\django\core\serializers\json.py
在 Deserializer 方法中找到这行代码
stream_or_string = stream_or_string.decode()
改成这样
stream_or_string = stream_or_string.decode('UTF-16')
再进行导入操作
参考资料
- https://docs.djangoproject.com/en/4.1/ref/django-admin/
- https://www.shubhamdipt.com/blog/django-transfer-data-from-sqlite-to-another-database/
- https://javaatpoint.com/solved-unicodedecodeerror-utf-8-codec-cant-decode-byte-0xff-in-position-0-invalid-start-byte/
- https://counter2015.com/2020/01/15/django-migration-sqlite-to-postgre/
- https://stackoverflow.com/questions/64457733/django-dumpdata-fails-on-special-characters
Django更换数据库和迁移数据方案的更多相关文章
- finedb(内置的HSQL数据库)迁移数据到MySQL
finedb(内置的HSQL数据库)迁移数据到MySQL 1. 前言 在FineBI中,决策平台的数据(用户.角色.组织机构.权限等信息)是存储在finedb数据库中的,默认情况下finedb是一个内 ...
- Django创建模型,迁移数据
1.在models.py文件中添加代码 class notice(models.Model): notice_title = models.CharField(max_length=255) noti ...
- django 给数据库批量添加数据
from .models import Book import random def index(request): book_list = [] for i in range(1, 101): bo ...
- django更换数据库时提示"django.db.utils.InternalError: (1366, "Incorrect string value: '\\xE7\\x94\\xA8\\xE6\\x88\\xB7' for column 'name' at row 1")"
问题提出 昨天在运行django时,初始化使用的是自带的数据库,后来更换mysql数据库,数据库同步之后,打开mysql无法添加数据,插入数据时,提示django.db.utils.InternalE ...
- 使用Django清理数据库中的数据
数据库,数据清洗 问题叙述性说明:在系统我用在,因为历史和由于各种原因,原因记录的数据内的数据库表,有一个问题,有反复和不完整的数据 解:首先.由于数据量还是挺大的,工的清理肯定不行, 然后,我就想写 ...
- mysql 5.7 迁移数据方案
从一台服务器迁移至其他服务器,如何选择最短的停服时间方案 方案一.凌晨3点的全备份+停服后一天的大概一天的增备 1. 拷贝前一天的全备份至新的服务器 rsync -auzrP /Data/dbbak/ ...
- Django向数据库批量插入数据
# 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...
- Django: 之数据库导入、迁移和联用
Django 数据库导入 从网上下载的一些数据,excel表格,xml文件,txt文件等有时候我们想把它导入数据库,应该如何操作呢? 以下操作符合 Django版本为 1.6 ,兼顾 Django 1 ...
- 阿里云RDS数据库改造迁移方案
1. 改造原因 (1) 由于历史原因, 本应该是同一个库的表分布在两个数据库中,需要对这两个库进行合并. (2) 已有的数据库性能无法满足业务的增长需要, 查询卡,慢问题突出. (3) 当前自建Mys ...
随机推荐
- 1.4_HTML的标签简介
HTML 标签 HTML 标记标签通常被称为 HTML 标签 (HTML tag). HTML 标签是由尖括号包围的关键词,比如 <html> HTML 标签通常是成对!出现的,比如 &l ...
- Shiro反序列化利用
Shiro反序列化利用 前言:hvv单位这个漏洞挺多的,之前没专门研究打法,特有此篇文章. Shiro rememberMe反序列化漏洞(Shiro-550) 漏洞原理 Apache Shiro框架提 ...
- 解决报错:axios is not defined
好家伙,来解决报错:axios is not defined 写前端嘛,修bug,不寒颤 进入页面一片空白 来看看报错: 1.axios在安装时:npm install axios --save-de ...
- 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(17)-Fiddler如何充当第三者,再识AutoResponder标签-下篇
1.简介 上一篇宏哥主要讲解的一些在电脑端的操作和应用,今天宏哥讲解和分享一下,在移动端的操作和应用.其实移动端和PC端都是一样的操作,按照宏哥前边抓取移动端包设置好,就可以开始实战了. 2.界面功能 ...
- Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述
好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...
- KFS replicator安装(Mysql-KES)
源端mysql 一.安装前置配置 1.创建安装用户 groupadd flysync useradd flysync -g flysync -G mysql passwd flysync 2.上传安装 ...
- 通过VS下载的NuGet包,如何修改其下载存放路径?
一.了解NuGet包的默认存放路径 我们通过NuGet包管理器下载的引用包,默认是存放在C盘的,存储路径一般是: C:\Users\{系统用户名}\.nuget\packages 我们都知道,C盘的存 ...
- Web开发框架『express』的基本使用 —— { }
基本 res.send([body]) 和 res.end([data] [, encoding]) 的区别 1.参数的区别: res.send([body]): body这个参数可以是[Buffer ...
- 邮箱的代理发送Send as权限不生效
邮箱的代理发送Sendas权限不生效 最近,有需求为用户添加其它邮箱的代理发送Sendas权限.在Exchange的管理单元里添加完毕后,发现没有效果,客户端提示你没有权限以用户的名义发送邮件 ...
- 重要参考步骤---ProxySQL Cluster 集群搭建步骤
环境 proxysql-1:192.168.20.202 proxysql-2:192.168.20.203 均采用yum方式安装 # cat <<EOF | tee /etc/yum.r ...