数据库替换(sqlite3 -> postgres)
背景
初期开发方便,没有考虑数据库限制,后期内部系统数据量到达一定量级后需要更换数据库,且需保持数据迁移。
注意事项:
- 需在项目的运行环境(venv)下执行操作
- 项目需暂停使用(不要再有数据变化)
- 按文章内容 顺序执行
-
settings配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
-
导出数据
python manage.py dumpdata > xxx.json
(如果有app下migrations 和 django_migrations 表数据不一致时,有较大概率出现问题,需要自己处理下字段和同步记录一致问题。语法略,常用 --exclude --indent)
-
安装配置postgres数据库(安装略)
-
安装略(数据库、django插件库postgresql_psycopg2)
-
创建数据库
# 进入postgres su - postgres # 创建用户 createuser --interactive -P # 用户名、密码 core_django_test xxxxx # 是否超级用户 y/n # 创建数据库db_core createdb --owner core_django_test db_core_test #退出 logout
-
查看数据库
# 进入dbshell python manage.py dbshell # 查看当前数据库信息 \l
-
-
修改settings文件数据库配置
# DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } # } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'db_core_test', 'USER': 'core_django_test', 'PASSWORD': 'kI6FCvldcEqQ8bho2qj7', 'HOST': 'localhost', 'PORT': '', } }
-
导入数据
-
同步数据库
# migrations、migrate python manage.py migrate python manage.py migrate --run-syncdb
-
导入数据
python manage.py loaddata xxx.json
-
大概率报错问题解决方案
django.db.utils.DataError: Problem installing fixture '/var/www/core/1510.json': Could not load interview.SingleChoiceQuestion(pk=71): value too long for type character varying(120)
(长度问题,sqlite3数据检查不严格,max_lenth=10, 也可以存储超过10的内容)
解决办法:
重新修改报错位置的字段长度,后同步数据库,makemigrations、migratedjango.db.utils.IntegrityError: Problem installing fixture '/var/www/core/1510.json': Could not load contenttypes.ContentType(pk=16): duplicate key value violates unique constraint "django_content_type_app_label_model_76bd3d3b_uniq" DETAIL: Key (app_label, model)=(book, group) already exists.
(content_type特点,默认已存储有 表-model,model-field信息,需要先删除,再导入数据。
注意,每次有migrations、migrate同步操作都需要执行下面的操作)
解决办法:
# 进入shell模式 python3 manage.py shell # 执行删除命令 from django.contrib.contenttypes.models import ContentType ContentType.objects.all().delete() # 完成退出 quit()
-