python Django学习(5.1)——连接mysql

前言

    django基本的一些知识已经学到(包括project和app的创建、路由的分发、前后端的交互等),这里就来记录一下django如何使用数据库以及如何连接mysql。

一、数据表的创建

    在django中创建数据表是在models.py中来创建的(前面也说过models.py是用来操作数据表的)。那么我们就先在models.py中创建一个数据表(ORM就不做介绍了,在python mysql orm框架----sqlalchemy(一)我也简单提到过):
models.py:

from django.db import models

# Create your models here.
# 数据默认是生成在db.sqlite3中,要想用自己的数据库,就去配置文件settings.py中修改


# 生成的表名叫:app01_userinfo
class UserInfo(models.Model):
    # Django会自动创建一列id列,是自增的,并且是主键
    # 用户名列,字符串类型,指定长度
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

    在上面这个类中,我们创建了一个userinfo的数据表,这个表在数据库中的名称为:app01_userinfo(因为我是在app01中创建的),其中创建了两列:username、password。当然,Django会自动为我们创建一列id列,这列是自增的,并且是主键。
    在创建数据表的代码写完后,接下来该如何操作呢?
    接下来就该根据我们的models.py来生成数据表了。
    先在终端中执行命令:

python manage.py makemigrations

    这时候migrations文件夹就该起作用了,会在这个文件夹中生成一个文件:0001_initial.py:

# Generated by Django 2.2.6 on 2019-10-10 13:27

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='UserInfo',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('username', models.CharField(max_length=32)),
                ('password', models.CharField(max_length=64)),
            ],
        ),
    ]

    前面也提到过,当数据库表结构发生变化的时候,migrations文件夹中就会有相应的记录,具体怎么记录,这里就有了。
    接下来执行命令:

python manage.py migrate

    这时候数据表就生成了,但并不是生成在我们的mysql中,而是生成在了Django自带的sqlite中。
在这里插入图片描述
    就是这个db.sqlite3中。
    那么我们又该如何来使用我们自己的mysql呢?接下来就来介绍。

二、Django连接mysql

    首先要确保我们的机器mysql安装成功。如果没有mysql,则需要先安装mysql。
    然后在settings.py中配置mysql。
    在settings.py中找到DATABASES:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # 默认用sqlite
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

    从这里可以看到django默认连接的是sqlite。接下来就将DATABASES配置成mysql:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'cmdb',
        'USER':'root',
        'PASSWORD':'123456',
        'HOST':'localhost',
        'POST':'3306',
    }
}

    注意:这里需要我们做的有以下几点:

  • 将’django.db.backends.sqlite3’改成’django.db.backends.mysql’;
  • 在我们自己的mysql中创建一个数据表叫cmdb,也就是配置里面的:‘NAME’: ‘cmdb’,(当然,也可以叫别的名称);
  • USER和PASSWORD就是mysql中的用户名和密码;
  • HOST和POST也要填上。
        如果不知道HOST和POST的,可以使用以下方法来获取:
    (1)进入数据库
mysql -u root -p

(2)在mysql中输入status:

mysql> status
--------------
C:\mysql\mysql-8.0.17-winx64\bin\mysql.exe  Ver 8.0.17 for Win64 on x86_64 (MySQL Community Server - GPL)

Connection id:          18
Current database:
Current user:           root@localhost
SSL:                    Cipher in use is DHE-RSA-AES128-GCM-SHA256
Using delimiter:        ;
Server version:         8.0.17 MySQL Community Server - GPL
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    gbk
Conn.  characterset:    gbk
TCP port:               3306
Uptime:                 12 hours 31 min 53 sec

    Connection: localhost via TCP/IP;这个就是HOST(填localhost就可以);
    TCP port: 3306;这个是PORT。
    在settings.py中配置好数据库后重复:

python manage.py makemigrations
python manage.py migrate

    这里会有很多问题,接下来我们一一解决。

问题一:

    问题描述:

ModuleNotFoundError: No module named 'MySQLdb'

    这里的问题是没有“MySQLdb”,我们是不是需要下载MySQLdb呢?
    注意:Django使用的与mysql交互的工具是MySQLdb,而我们之前使用的都是pymysql或者mysql-connector。在这里,我们不需要下载MySQLdb,只需要在与项目同名的文件夹下的__init_.py中加入以下代码就可以:

import pymysql
pymysql.install_as_MySQLdb()

    加入这个代码以后,再次执行上面的两个命令:

python manage.py makemigrations
python manage.py migrate
问题二:

    问题描述:

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.  
File “C:\Python37\lib\site-packages\django\db\backends\mysql\operations.py”, line 146, in last_executed_query   
query = query.decode(errors=‘replace’)   
AttributeError:strobject has no attribute ‘decode’   

    这里其实是两个小问题,先来看第一个问题,第一个问题说的是mysqlclient 版本低,我们第一个想法肯定是升级mysqlclient ,但是先别着急,这里的问题并不是mysqlclient 版本低,而是django2.2内部的一个版本限制在作怪(我用的是django2.2.6),我们只需要修改源码就行。找到mysql下的base.py,将里面的raise ImproperlyConfigured(‘mysqlclient 1.3.13 or newer is required; you have %s.’ % Database.version)注释掉:

# Some of these import MySQLdb, so import them after checking if it's installed.
from .client import DatabaseClient                          # isort:skip
from .creation import DatabaseCreation                      # isort:skip
from .features import DatabaseFeatures                      # isort:skip
from .introspection import DatabaseIntrospection            # isort:skip
from .operations import DatabaseOperations                  # isort:skip
from .schema import DatabaseSchemaEditor                    # isort:skip
from .validation import DatabaseValidation                  # isort:skip


# 主要是这里
version = Database.version_info
# if version < (1, 3, 13):
#     raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)

    对于第二个问题,将源码中的decode改成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.encode(errors='replace')			# 主要是这里,一开始是decode,改成encode
        return query

    将问题解决后,再次执行命令:

python manage.py makemigrations

    结果:

No changes detected

注:这里没有变化的原因是我在上面已经执行过一次了,那个时候是连接的sqlite,接下来我也没有做数据表的修改,所以这里是没有变化的

python manage.py migrate

    结果:

Operations to perform:
  Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying app01.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

    看代码的执行结果似乎是成功了,那么就去mysql中看看是不是真的创建上数据表了:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| cmdb               |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use cmdb;
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_cmdb             |
+----------------------------+
| app01_userinfo             |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)

mysql> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | NO   |     | NULL    |                |
| password | varchar(64) | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql>

    在上面我们也提到过,生成的数据表的名字是:app01_userinfo,cmdb中也有这个表,我们desc一下发现里面的列也是我们创建的列,当然这里多出一列id来,这里上面也解释过了。
    这里有个问题,在cmdb中除了我们自己创建的表以外,还有另外的10个表,这是怎么回事呢?
    这是因为django内部的需要,所以在创建我们表的同时,也会创建出额外的表来。
    可以简单看一下那些表是干什么的,随便打开一个:

mysql> desc auth_user;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| password     | varchar(128) | NO   |     | NULL    |                |
| last_login   | datetime(6)  | YES  |     | NULL    |                |
| is_superuser | tinyint(1)   | NO   |     | NULL    |                |
| username     | varchar(150) | NO   | UNI | NULL    |                |
| first_name   | varchar(30)  | NO   |     | NULL    |                |
| last_name    | varchar(150) | NO   |     | NULL    |                |
| email        | varchar(254) | NO   |     | NULL    |                |
| is_staff     | tinyint(1)   | NO   |     | NULL    |                |
| is_active    | tinyint(1)   | NO   |     | NULL    |                |
| date_joined  | datetime(6)  | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
11 rows in set (0.01 sec)

    当然,这些表的具体作用我还在探索当中,如果有小伙伴知道,欢迎评论区留言!!

写在最后

    本文是个人的一些学习笔记,如有侵权,请及时联系我进行删除,谢谢大家.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值