Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django 项目配置 MySQL #139

Open
Qingquan-Li opened this issue Dec 12, 2019 · 0 comments
Open

Django 项目配置 MySQL #139

Qingquan-Li opened this issue Dec 12, 2019 · 0 comments

Comments

@Qingquan-Li
Copy link
Owner

Qingquan-Li commented Dec 12, 2019

环境:

  • MySQL Community Server 5.7.28
  • Django 2.2
  • Python 3.7
  • PyMySQL 0.9.3
  • macOS 10.12.6
  • 包(环境)管理器:conda

参考:


一、为 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant