blog
blog copied to clipboard
Django 项目配置 MySQL
环境:
- MySQL Community Server 5.7.28
- Django 2.2
- Python 3.7
- PyMySQL 0.9.3
- macOS 10.12.6
- 包(环境)管理器:conda
参考:
- Django文档 - 配置 - DATABASES
- Django文档 - 数据库 - MySQL notes
- macOS安装MySQL 5.7.28
- PyMySQL - GitHub
- MySQL的编码问题
- 常用 SQL 语句( MySQL )
一、为 Django 项目创建数据库
# 连接 MySQL ,语法:$ mysql -h host -u user -p
# 这里是:$ mysql -u root -p
# 创建数据库:
# 这样可以确保所有表和列在默认情况下都将使用UTF-8:
mysql> CREATE DATABASE <dbname> CHARACTER SET utf8;
# 建议:创建数据库,设置 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci:
mysql> CREATE DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
二、安装 pymysql 驱动
Django 3.1 文档(https://docs.djangoproject.com/zh-hans/3.1/ref/databases/#mysql-notes) 推荐使用 mysqlclient :mysqlclient is a native driver. It's the recommended choice. 执行
$ conda install mysqlclient
安装 mysqlclient 后,不需要其他配置即可连接 MySQL 。
# 安装 pymysql
# pymysql 是 python 驱动 MySQL 时使用的库(驱动程序),Python interface to MySQL
$ conda install pymysql
# 另还有官方推荐的驱动程序: mysqlclient is a native driver. It's the recommended(推荐) choice.
# mysqlclient 由 C 语言编写,操作 SQL 效率更高;pymysql 由 Python 编写,执行效率较低但易于配置部署。
三、配置 Django 项目的数据库设置
# settings.py数据库默认配置
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
# }
# Django 项目数据库改为 MySQL
# 导入 pymysql 库(驱动程序)
import pymysql
# MySQLdb是以前使用的原生的库(Python驱动MySQL的驱动程序),但已经不支持新版python3,使用pymysql代替。
pymysql.install_as_MySQLdb()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysite', # 数据库名,需要提前创建好
'USER': 'root', # 用户名
'PASSWORD': 'password', # 密码
'HOST': '127.0.0.1', # mysql服务所在的主机ip
'PORT': '3306', # mysql服务端口,默认为3306
}
}
四、运行
$ python manage.py makemigrations # 生成迁移文件
$ python manage.py migrate # 应用数据库迁移
$ sudo /usr/local/mysql/support-files/mysql.server restart # macOS重启MySQL
$ sudo /usr/local/mysql/support-files/mysql.server start # macOS启动MySQL
$ sudo /usr/local/mysql/support-files/mysql.server stop # macOS关闭MySQL
$ sudo /usr/local/mysql/support-files/mysql.server status # 查看MySQL状态
# 创建一个管理员账号:
$ python manage.py createsuperuser
Username: admin
Email address: [email protected]
Password: **********
Password (again): *********
Superuser created successfully.
$ python manage.py runserver <ip>:<port>
附:pymysql(mysqlclient)版本报错解决方案
# 如果执行 $ python manage.py makemigrations 生成迁移文件时,报错如下:
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
此处此时(2019.12)因为安装的是 pymysql 0.9.3 ,不支持 Django 2.2 ,解决方案参考:https://stackoverflow.com/questions/55657752/django-installing-mysqlclient-error-mysqlclient-1-3-13-or-newer-is-required
注意:
2020年07月18日发布的 pymysql 0.10.0 似乎解决了以上问题,所以不再需要修改以下的 base.py 文件。但是,执行 python manage.py migrate
,依然会报错:query = query.decode(errors='replace') AttributeError: 'str' object has no attribute 'decode'
,所以依然需要修改以下的 operations.py 文件。
实例:
修改源码:打开虚拟环境路径(这里是 /anaconda3/envs/lottery_env )+ /lib/python3.7/site-packages/django/db/backends/mysql
第一步: 打开 base.py 文件 ==> 搜索 version = Database.version_info
==> 在 if
语句中放入 pass
并注释原来的命令行输出 ==> 保存文件:
version = Database.version_info
if version < (1, 3, 13):
# raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
pass # 修改为pass by Fatli 20191215
第二步: 打开 operations.py 文件 ==> 搜索 query = query.decode(errors='replace')
==> change decode to encode ==> 保存文件:
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
query = getattr(cursor, '_executed', None)
if query is not None:
# query = query.decode(errors='replace')
query = query.encode(errors='replace') # 修改 by Fatli 20191215
return query
Now, try to run the server.
附:记录配置 mysqlclient 的一些坑,请忽略
$ conda install mysqlclient # 安装 mysqlclient 驱动程序(用以 Python驱动 MySQL)
# 使用 mysqlclient 后报错:
django.db.utils.OperationalError: (2026, 'SSL connection error: SSL_CTX_set_tmp_dh failed')
# 解决方案:https://stackoverflow.com/questions/53385113/django-db-utils-operationalerror-2026-ssl-connection-error-ssl-ctx-set-tmp
# 方案一:添加配置use_pure=True,失败。
# 方案二:bin/mysql_ssl_rsa_setup,调整ssl
# https://dev.mysql.com/doc/refman/5.7/en/data-directory-initialization.html
# 方案三:简单粗暴的方法,给openssl降级,原来是openssl 1.1.1d | conda-forge
$ conda install openssl=1.0.2r
# 验证了不可行,将会报错:
conda-forge/osx-64::python==3.7.3=h93065d6_1 -> openssl[version='>=1.1.1a,<1.1.2a']
# DATABASES设置为'read_default_file': './my.cnf'后报错:
# django.db.utils.OperationalError: (1045, "Access denied for user 'fatli'@'localhost' (using password: NO)")
# 解决方案(无效,依然报错如上):
# https://stackoverflow.com/questions/10299148/mysql-error-1045-28000-access-denied-for-user-billlocalhost-using-passw
mysql> SELECT USER(), CURRENT_USER();
+----------------+----------------+
| USER() | CURRENT_USER() |
+----------------+----------------+
| root@localhost | root@localhost |
+----------------+----------------+
1 row in set (0.00 sec)
mysql> SHOW GRANTS FOR 'fatli'@'localhost';
ERROR 1141 (42000): There is no such grant defined for user 'fatli' on host 'localhost'
mysql> SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
# 给 fatli 权限(依然报同样的错)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'fatli'@'localhost' IDENTIFIED BY 'Syy31=root' WITH GRANT OPTION;
# 设置mysql文件权限给fatli ==> 依然无效
(mysite_copy_env) ➜ /usr/local/mysql-5.7.28-macos10.14-x86_64 > ls -la
total 560
drwxr-xr-x 13 root wheel 442 12 3 15:38 .
drwxr-xr-x 17 root wheel 578 12 3 15:38 ..
-rw-r--r-- 1 root wheel 279547 9 27 15:00 LICENSE
-rw-r--r-- 1 root wheel 587 9 27 15:00 README
drwxr-xr-x 40 root wheel 1360 9 27 19:30 bin
drwxr-x--- 23 _mysql _mysql 782 12 10 13:44 data
drwxr-xr-x 5 root wheel 170 9 27 19:30 docs
drwxr-xr-x 50 root wheel 1700 9 27 19:30 include
drwxr-x--- 3 _mysql _mysql 102 12 3 18:22 keyring
drwxr-xr-x 11 root wheel 374 12 3 15:38 lib
drwxr-xr-x 4 root wheel 136 9 27 19:30 man
drwxr-xr-x 39 root wheel 1326 9 27 19:30 share
drwxr-xr-x 6 root wheel 204 9 27 19:30 support-files
$ sudo chmod -R 777 /usr/local/mysql-5.7.28-macos10.14-x86_64
$ sudo chown -R _mysql /usr/local/mysql-5.7.28-macos10.14-x86_64
# r:4
# w:2
# x:1