Django 从SQLite迁移到PostgreSQL
问题背景
创建Django项目时,默认创建的数据库是SQLite,这可以方便我们进行原型开发。
但是,随着项目的进行和需求的变化,就逐渐变得不再适合了。
我遇到的问题就是
- SQLite不能支持超过999的字段
- SQLite大量数据写入时表现很差
稍微查了下资料对比了下目前我知道的两个数据库
周围有人不听地吹PostgreSQL(以下简称pg)的特性多么多么强大,那就用起来吧。
其实之前也有尝试着搭过,算是一回生,二回熟了?
以下步骤基于如下环境
- 系统 CentOS 7
- 数据库 PostgreSQL 12
- Django 2.2
- Python 3.6
迁移前切记,先备份数据库。
PostgreSQL下载安装
之前在ubuntu环境下安装过pg,现在简单讲下在CentOS环境下安装步骤
参考: https://www.postgresql.org/download/linux/redhat/
1 | yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm |
设置对应的表和用户/密码/权限
1 | su postgres |
修改配置,允许外部访问
1 | 需要修改配置文件 postgresql.conf, 确定其位置有两个方法 |
找到如下部分的配置文件
1 | ------------------------------------------------------------------------------ |
修改listen_addresses
配置项(同时去除注释)为
listen_addresses = '*'
修改port
配置项(同时去除注释)为 15432
这里是我为了防止可能的端口冲突,可以根据需要自己选择是否修改
修改配置文件
1 | vim /var/lib/pgsql/12/data/pg_hba.conf |
在文件末尾添加如下一行
这将会允许从外部所有地址的连接(注意潜在的安全问题)。
修改完成后,需要重启数据库以使配置文件生效
1 | systemctl restart postgresql-12 |
这样就可以从客户端远程访问数据库了(比如说服务端的host为mycentos)
1 | psql -h mycentos -p 15432 -U myuser -d mydb |
可选: 数据可视化工具的安装
这方面最有名的工具就是Navicat了,但是我不用,因为(没钱
下面介绍的是开源的dbeaver(海狸)
用起来感觉还不错
数据和表的迁移
分为以下几个步骤
将数据从SQLite中导出成文件
在PostgreSQL中重新创建对应的表结构
将数据文件导入到PostgreSQL中
将Django的后端数据库驱动切换成PostgreSQL,并配置对应的数据库连接信息
导出可以借助Django自带的工具
1 | python3 manage.py dumpdata > datadump.json |
安装Python - PostgreSQL驱动
1 | pip3 install psycopg2-binary |
修改settings.py
1 | DATABASES = { |
执行表结构的迁移
1 | 你可能需要激活虚拟环境 |
数据的导入
1 | python3 manage.py loaddata datadump.json |
这里我遇到了两个小坑
1 | django.db.utils.IntegrityError: Problem installing fixtures: 错误: 插入或更新表 "predicts" 违反外键约束 "predicts_dataset_id_9ffd0177_fk_mark_datasets_id" |
这是SQLite对级联删除的支持问题
尽管我在models.py
中声明了models.ForeignKey(DataSets, on_delete=models.CASCADE, null=True, blank=True)
但是从数据库直接删除(而不是通过Django 的ORM ( Object Relational Mapping )删除)的时候,并没有做级联删除于是我还得手动删除
1 | psycopg2.errors.UniqueViolation: 错误: 重复键违反唯一约束"django_content_type_app_label_model_76bd3d3b_uniq" |
这里有两种解决方法
方法一:重新导出数据
1 | python3 manage.py dumpdata --natural-primary --natural-foreign > data.json |
方法二:删除content_type
(没搞懂原理)
1 | python3 manage.py shell |
使用上面任意一个方法后,重新加载数据
1 | python3 manage.py loaddata datadump.json |
如果有使用raw SQL操作数据库,需要对比两个数据库的不同API,进行业务代码层面的修改
这里我用的都是ORM操作,所以没有这个问题。
至此,迁移工作就基本完成了。
参考链接
- How to migrate your Django project from SQLite to PostgreSQL
- Creating user, database and adding access on PostgreSQL
- How to enable remote access to PostgreSQL server on a Plesk server?
- HowTo Safely Open a PostgreSQL Port for Remote Access?
- PostgreSQL doc: The pg_hba.conf File
- Postgres login: How to log into a Postgresql database
- How To Use PostgreSQL with your Django Application on Ubuntu 14.04
- Django when I try to migrate migrations to PostgreSQL it throws a exceptions psycopg2.ProgrammingError
版权声明:
除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 进行许可。
分享