返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Django

Django Database Switch and Data Migration Solution

Introduction I was so busy shopping during Double 11 that I barely wrote any articles. There are still a dozen unfinished draft articles in my notes… Today I'll share a solution for switching databases and migrating data in a Django project. Articles found online vary in their methods, and you're likely to run into all kinds of errors when using them. This article is based on Django's official documentation and work experience—stable and reliable, and I'll keep it updated on the blog~ If you're facing the same problem, reading this article should give you a pretty good solution. Basic Steps Django uses SQLite by default for convenient development, and

曦远 (DealiAxy)约 15 分钟
目录14 个章节

Introduction

I was so busy shopping during Double 11 that I barely wrote any articles. There are still a dozen unfinished draft articles in my notes…

Today I'll share a solution for switching databases and migrating data in a Django project. Articles found online vary in their methods, and you're likely to run into all kinds of errors when using them. This article is based on Django's official documentation and work experience—stable and reliable, and I'll keep it updated on the blog~

If you're facing the same problem, reading this article should give you a pretty good solution.

Basic Steps

Django uses SQLite by default for convenient development, and its ORM supports multiple databases—you just need to install the corresponding driver.

Switching databases typically means moving from SQLite in the development environment to MySQL (MariaDB) or PostgreSql. This article only tested switching from SQLite to MySQL / PostgreSQL; similarly, other switch paths should work as well.

The database table structure isn't really a problem—just use Django's migrate feature.

The key is data migration. You can use database tools like Navicat for data sync, but it often fails due to constraint relationships between tables (requiring data to be imported in a specific order).

So the best approach is to use Django's dumpdata feature to export the database as a json or xml file, then switch databases and import.

The steps are as follows:

  • Export existing data: python manage.py dumpdata -o db.json
  • Create an empty database in the target database (MySQL / PostgreSql)
  • Switch to the new database in settings.py
  • Set up the new database table structure python manage.py migrate
  • Import existing data: python manage.py loaddata db.json

Done~

Here are a few database configurations for convenience

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']}

Notes:

  • MySQL requires installing the mysqlclient package
  • PostgreSql requires installing the psycopg2 package

Then again, things often aren't that simple and smooth. You may run into some issues during export and import—please read on~

Export Errors

Error message

CommandError: Unable to serialize database: 'gbk' codec can't encode character '\u30fb' in position 4: illegal multibyte sequence

The cause is related to encoding

Solution

Exporting data with Python's UTF-8 mode will work fine

Use this command to export the file

(Do not export auth.permission and contenttypes; these two are auto-generated during migrate, which avoids conflicts when importing the original data)

python -Xutf8 manage.py dumpdata --exclude auth.permission --exclude contenttypes > db.json

Or

python -Xutf8 manage.py dumpdata -o db.json

Fixing Errors During Import

Error 1: Duplicate entry

Error message

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'")

Solution 1: Re-export the data

Add these two parameters

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

The effect is to strip some constraints on export; they will be handled automatically on import, reducing issues caused by constraint relationships between tables during import.

python3 manage.py dumpdata --natural-primary --natural-foreign -o db.json

Solution 2: Delete content_type data

Another approach: delete the initialization data produced by the migrate process to avoid conflicts with the original data on import.

First enter the python shell

python3 manage.py shell

Enter and run the following Python code

from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()

Error 2: Encoding error

Error message

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xff in position 0: invalid start byte in Django

Add the -Xutf8 parameter before the import command

python -Xutf8 manage.py loaddata db.json

Solution 2: Hack Django's code

It works, but it's not recommended. Only try this method if you really have no other choice.

Modify the file

lib\site-packages\django\core\serializers\json.py

Find this line of code in the Deserializer method

stream_or_string = stream_or_string.decode()

Change it to this

stream_or_string = stream_or_string.decode('UTF-16')

Then proceed with the import

References

_EOF_

Django Database Switch and Data Migration Solution

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

Django+Taro项目实现企业微信登录

前言 还是最近在做的一个小项目,后端用的是Django搭配RestFramework做接口,前端第一次尝试用京东开源的Taro框架来做多端(目前需要做用于企业微信的H5端和微信小程序) 本文记录一下企业微信登录的流程,上周看文档看得头晕晕的,其实很简单,封装好了就几行代码的事~ 两种方式 一种是先拼接好登录要用的地址authorize_url,回调地址设置成h5应用的网页入口,然后把authori

2022-04-08 · Django · 约 1 分钟

Django中「强行」使用MVVM设计模式

扫盲 首先带大家了解一下什么是MVVM模式: 什么是MVVM?MVVM是Model-View-ViewModel的缩写。 MVVM是MVC的增强版,实质上和MVC没有本质区别,只是代码的位置变动而已 从名字上看,MVVM比MVC架构中多了一个ViewModel,没错,就是这个ViewModel,他是MVVM相对于MVC改进的核心思想。在开发过程中,由于需求的变更或添加,项目的复杂度越来越高,代码量

2021-12-18 · Django · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…