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 ...
随机推荐
- PTA C语言作业
6-1 使用函数输出一个整数的逆序数 (20 分) 本题要求实现一个求整数的逆序数的简单函数. 函数接口定义: int reverse( int number ); 其中函数reverse须返回用户 ...
- 网站SQL注入之数字型注入和字符型注入
什么是SQL注入- (SQL Injection)是一种常见的Web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击.1,是一种将SQL语句插入或添加到应用(用户)的 ...
- C++基础入门:C++初始
1. C++环境:Clion搭建 下载链接:clion官方网址 1.1 点击下载 1.2 下载对应版本 1.3 安装步骤: 1.3.1 下载完毕后,打开exe文件,进入安装界面,点击[Next > ...
- 【设计模式】Java设计模式 - 原型模式
[设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...
- 微服务系列之网关(二) konga配置操作
1.konga核心对象 Kong 的四大核心对象:upstream,target,service,route.下面分别说: (1)upstream,字面意思上游,实际项目理解是对某一个服务的一个或者多 ...
- Go语言学习的坑爹历程
鄙人暑期实习,需要用Go语言进行编程 在go语言中,结构体的定义只支持变量的声明,成员函数是采用"接口方法"来实现的 留一个成员定义的模板在此 package main impor ...
- C#/VB.NET 在Word文档中插入分页符
分页符是分页的一种符号,上一页结束以及下一页开始的位置.通查用于在指定位置强制分页.本文将分为两部分来介绍如何在Word文档中插入分页符.并附上C#/VB.NET以供参考,详情请阅读以下内容. 在特定 ...
- haodoop概念总结
大数据部门组织结构 Hadoop的优势(4高) 高可靠性:Hadoop底层维护多个数据副本 高扩展性:在集群间分配任务数据,可方便的扩展 高效性:在MapReduce的思想下,Hadoop时并行工作的 ...
- 如何搭建安全的 CI/CD 管道?
Eolink 前端负责人黎芷君进行了<工程化- CI / CD>的主题演讲,围绕 CI/CD 管道安全的实践,分享自己在搭建 CI/CD 管道过程中所总结的重要经验,与开发者深入讨论 &q ...
- Windows磁盘容量差异
如果足够细心,你就能发现计算机管理里面显示的容量和我的电脑里面磁盘容量的显示有差异.我的电脑中显示的总会少一点. https://www.cnblogs.com/qishine/p/12125329. ...