Qingquan-Li / blog

My Blog
https://Qingquan-Li.github.io/blog/
132 stars 16 forks source link

Django 项目配置 MySQL #139

Open Qingquan-Li opened 4 years ago

Qingquan-Li commented 4 years ago

环境:

参考:


一、为 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: admin@example.com
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