前言

双十一光顾着买东西都没怎么写文章,现在笔记里还有十几篇半成品文章没写完…

今天来分享一下 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.permissioncontenttypes ,这俩在 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')

再进行导入操作

参考资料

Django更换数据库和迁移数据方案的更多相关文章

  1. finedb(内置的HSQL数据库)迁移数据到MySQL

    finedb(内置的HSQL数据库)迁移数据到MySQL 1. 前言 在FineBI中,决策平台的数据(用户.角色.组织机构.权限等信息)是存储在finedb数据库中的,默认情况下finedb是一个内 ...

  2. Django创建模型,迁移数据

    1.在models.py文件中添加代码 class notice(models.Model): notice_title = models.CharField(max_length=255) noti ...

  3. django 给数据库批量添加数据

    from .models import Book import random def index(request): book_list = [] for i in range(1, 101): bo ...

  4. 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 ...

  5. 使用Django清理数据库中的数据

    数据库,数据清洗 问题叙述性说明:在系统我用在,因为历史和由于各种原因,原因记录的数据内的数据库表,有一个问题,有反复和不完整的数据 解:首先.由于数据量还是挺大的,工的清理肯定不行, 然后,我就想写 ...

  6. mysql 5.7 迁移数据方案

    从一台服务器迁移至其他服务器,如何选择最短的停服时间方案 方案一.凌晨3点的全备份+停服后一天的大概一天的增备 1. 拷贝前一天的全备份至新的服务器 rsync -auzrP /Data/dbbak/ ...

  7. Django向数据库批量插入数据

    # 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...

  8. Django: 之数据库导入、迁移和联用

    Django 数据库导入 从网上下载的一些数据,excel表格,xml文件,txt文件等有时候我们想把它导入数据库,应该如何操作呢? 以下操作符合 Django版本为 1.6 ,兼顾 Django 1 ...

  9. 阿里云RDS数据库改造迁移方案

    1. 改造原因 (1) 由于历史原因, 本应该是同一个库的表分布在两个数据库中,需要对这两个库进行合并. (2) 已有的数据库性能无法满足业务的增长需要, 查询卡,慢问题突出. (3) 当前自建Mys ...

随机推荐

  1. 1.4_HTML的标签简介

    HTML 标签 HTML 标记标签通常被称为 HTML 标签 (HTML tag). HTML 标签是由尖括号包围的关键词,比如 <html> HTML 标签通常是成对!出现的,比如 &l ...

  2. Shiro反序列化利用

    Shiro反序列化利用 前言:hvv单位这个漏洞挺多的,之前没专门研究打法,特有此篇文章. Shiro rememberMe反序列化漏洞(Shiro-550) 漏洞原理 Apache Shiro框架提 ...

  3. 解决报错:axios is not defined

    好家伙,来解决报错:axios is not defined 写前端嘛,修bug,不寒颤 进入页面一片空白 来看看报错: 1.axios在安装时:npm install axios --save-de ...

  4. 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(17)-Fiddler如何充当第三者,再识AutoResponder标签-下篇

    1.简介 上一篇宏哥主要讲解的一些在电脑端的操作和应用,今天宏哥讲解和分享一下,在移动端的操作和应用.其实移动端和PC端都是一样的操作,按照宏哥前边抓取移动端包设置好,就可以开始实战了. 2.界面功能 ...

  5. Android平台摄像头/屏幕/外部数据采集及RTMP推送接口设计描述

    好多开发者提到,为什么大牛直播SDK的Android平台RTMP推送接口怎么这么多?不像一些开源或者商业RTMP推送一样,就几个接口,简单明了. 不解释,以Android平台RTMP推送模块常用接口, ...

  6. KFS replicator安装(Mysql-KES)

    源端mysql 一.安装前置配置 1.创建安装用户 groupadd flysync useradd flysync -g flysync -G mysql passwd flysync 2.上传安装 ...

  7. 通过VS下载的NuGet包,如何修改其下载存放路径?

    一.了解NuGet包的默认存放路径 我们通过NuGet包管理器下载的引用包,默认是存放在C盘的,存储路径一般是: C:\Users\{系统用户名}\.nuget\packages 我们都知道,C盘的存 ...

  8. Web开发框架『express』的基本使用 —— { }

    基本 res.send([body]) 和 res.end([data] [, encoding]) 的区别 1.参数的区别: res.send([body]): body这个参数可以是[Buffer ...

  9. 邮箱的代理发送Send as权限不生效

     邮箱的代理发送Sendas权限不生效 最近,有需求为用户添加其它邮箱的代理发送Sendas权限.在Exchange的管理单元里添加完毕后,发现没有效果,客户端提示你没有权限以用户的名义发送邮件 ...

  10. 重要参考步骤---ProxySQL Cluster 集群搭建步骤

    环境 proxysql-1:192.168.20.202 proxysql-2:192.168.20.203 均采用yum方式安装 # cat <<EOF | tee /etc/yum.r ...