Django之开发微信小程序后端-数据库模型层篇③

第5章 深入Django模型层之使用篇

在这里插入图片描述
在这里插入图片描述

5-2 数据库迁移

在这里插入图片描述

数据备份

(venv) D:\Python_projects\backend-3-9>python manage.py dumpdata --exclude=contenttypes --exclude=auth.Permission > mysite_alldata.json

表结构同步

在这里插入图片描述
Django默认可使用多个数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'slave': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'vx_backend',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
  • 同步数据库表结构
    python manage.py migrate --run-syncdb --database slave
(venv) D:\Python_projects\backend-3-9>python manage.py migrate --run-syncdb --database slave
Operations to perform:
  Synchronize unmigrated apps: messages, staticfiles
  Apply all migrations: admin, auth, authorization, contenttypes, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
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 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 authorization.0001_initial... OK
  Applying sessions.0001_initial... OK

(venv) D:\Python_projects\backend-3-9>

与sqllite数据库表结构都一样
在这里插入图片描述
在同步表结构后,DATABASE部分可以注释了
在这里插入图片描述

数据迁移

数据迁移

(venv) D:\Python_projects\backend-3-9>python manage.py loaddata mysite_alldata.json
Installed 81 object(s) from 1 fixture(s)

(venv) D:\Python_projects\backend-3-9>

5-3 数据库索引

索引概述

在这里插入图片描述

应该被索引的字段

在这里插入图片描述
更改model属性都需要

(venv) D:\Python_projects\backend-3-9>python manage.py makemigrations
Migrations for 'authorization':
  authorization\migrations\0002_auto_20200531_1818.py
    - Alter field nickname on user

(venv) D:\Python_projects\backend-3-9>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, authorization, contenttypes, sessions
Running migrations:
  Applying authorization.0002_auto_20200531_1818... OK

Diango添加索引两种方法

在这里插入图片描述

# Create your models here.
class User(models.Model):
    # open_id
    open_id = models.CharField(max_length=64, unique=True)
    # 昵称
    nickname = models.CharField(max_length=256) # index = True
    # 关注的城市
    focus_cities = models.TextField(default='[]')
    # 关注的星座
    focus_constellations = models.TextField(default='[]')
    # 关注的股票
    focus_stocks = models.TextField(default='[]')

    class Meta:
        indexes = [
            models.Index(fields=["open_id", "nickname"]),
            models.Index(fields=["nickname"])
        ]


在这里插入图片描述

扫描二维码关注公众号,回复: 11453575 查看本文章

5-4 关系映射

三种关系映射

在这里插入图片描述
在这里插入图片描述

Django表达三种映射

在这里插入图片描述

关系映射实战

在这里插入图片描述
根据 不同用户可以选择添加不同app应用,关系为多对多

app model

from django.db import models

# Create your models here.
# 入口功能清单描述
class App(models.Model):
    appid = models.CharField(primary_key=True, max_length=32)  # 唯一ID
    category = models.CharField(max_length=128)  # 分类
    application = models.CharField(max_length=128)  # 功能名字
    name = models.CharField(max_length=128)  # 中文名字
    publish_date = models.DateField()  # 发布时间
    url = models.CharField(max_length=128)  # 请求链接
    desc = models.TextField()  # 描述

    def to_dict(self):
        return {
            'appid': self.appid,
            'category': self.category,
            'application': self.application,
            'name': self.name,
            'publish_date': self.publish_date,
            'url': self.url,
            'desc': self.desc
        }

    def __str__(self):
        return str(self.to_dict())

    def __repr__(self):
        return str(self.to_dict())

用户model

# -*- encoding=utf8 -*-


from django.db import models
from apis.models import App

# Create your models here.
class User(models.Model):
    # open_id
    open_id = models.CharField(max_length=64, unique=True)
    # 昵称
    nickname = models.CharField(max_length=256, db_index=True)
    # 关注的城市
    focus_cities = models.TextField(default='[]')
    # 关注的星座
    focus_constellations = models.TextField(default='[]')
    # 关注的股票
    focus_stocks = models.TextField(default='[]')

    # 菜单app
    menu = models.ManyToManyField(App)

    class Meta:
        indexes = [
            # models.Index(fields=['nickname'])
            models.Index(fields=['open_id', 'nickname'])
(venv) D:\Python_projects\backend-3-9>python init.py
init.py:28: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  apps = yaml.load(f)
not exist, appid: f18ba49825b634f44e8cdfb694ecaa13
not exist, appid: 549eaaf72cb23716e2b1313acfaed23c
not exist, appid: 7b27422f98f13eb2610f1996ec757be7
not exist, appid: a381d410bea99d3618cc6cd431c32b0f
not exist, appid: 833cfd91bc1ac638ecd3764715b443ef

5-5 数据库操作

django使用原生SQL的方法

使用extra:

models.Book.objects.filter(publisher__name=‘传说中的申小五’).extra(where=[‘price>50’])
models.Book.objects.filter(publisher__name=‘传说中的申小五’, price__gt=50)

models.Book.objects.extra(select={‘count’: ‘select count(*) from hello_Book’})

使用raw:

Book.objects.raw(‘select * from hello_Book’) # 返回模型实例

执行自定义SQL语言:

from django.db import connection
​
cursor=connection.cursor()
​
cursor.execute("insert into hello_author(name) values('传说中的申小五')")
​
cursor.execute("update hello_author set name='abc' where name='bcd'")

cursor.execute("delete from hello_author where name='abc'")

cursor.execute("select * from hello_author")
​
raw=cursor.fetchone()  # 返回结果行游标直读向前,读取一条
cursor.fetchall()  # 读取所有

数据库函数

第6章 深入Django模型层之优化篇

6-1 章节导学

在这里插入图片描述

6-2 理解模型变更与迁移

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据变更的sql语句显示

(venv) D:\Python_projects\backend-3-9>python manage.py sqlmigrate authorization 0004
BEGIN;
--
-- Remove index authorizati_nicknam_b76290_idx from user
--
DROP INDEX `authorizati_nicknam_b76290_idx` ON `authorization_user`;
--
-- Add field menu to user
--
CREATE TABLE `authorization_user_menu` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `user_id` integer NOT NULL, `app_id` varchar(32) NOT NULL);
--
-- Alter field nickname on user
--
CREATE INDEX `authorization_user_nickname_248a4fcf` ON `authorization_user` (`nickname`);
ALTER TABLE `authorization_user_menu` ADD CONSTRAINT `authorization_user_m_user_id_b7aaa9f0_fk_authoriza` FOREIGN KEY (`user_id`) REFERENCES `authorization_user` (`id`);
ALTER TABLE `authorization_user_menu` ADD CONSTRAINT `authorization_user_menu_app_id_13ca5893_fk_apis_app_appid` FOREIGN KEY (`app_id`) REFERENCES `apis_app` (`appid`);
ALTER TABLE `authorization_user_menu` ADD CONSTRAINT authorization_user_menu_user_id_app_id_4d3d9382_uniq UNIQUE (`user_id`, `app_id`);
COMMIT;

历史迁移记录

(venv) D:\Python_projects\backend-3-9>python manage.py showmigrations authorization
authorization
 [X] 0001_initial
 [X] 0002_auto_20200531_1818
 [X] 0003_auto_20200531_1823
 [ ] 0004_auto_20200531_1912
(venv) D:\Python_projects\backend-3-9>

如果没有 X, 在说明没有执行 migrate到db

迁移文件详解

在这里插入图片描述

6-3 懒加载与预加载

在这里插入图片描述
在这里插入图片描述
使用python manage.py shell ,导入mode的类属性,使用query可以显示查询的sql语句。

预加载的两种方法

在这里插入图片描述
再用query属性看一下SQL语句,select_related()使用JOIN获取了模型的数据。这样就预先加载了外键关联的对象,再次调用关联对象时就不会访问数据库了。

6-4 数据库长连接

  • 尽少的链接次数,集中查询

    因为创建和关闭链接的时间和单词查询的时间类似,一开一关大大浪费性能

  • 避免负优化:

    使用CONN_MAX_AGE配置限制DB连接寿命

    CONN_MAX_AGE默认值是0

    每个DB连接的寿命保持到该次请求结束

    不建议开发模式下使用CONN_MAX_AGE

6-5 数据库操作规范

在这里插入图片描述

  • 判断是否应该建索引的条件

    1、较频繁的作为查询条件的字段应该创建索引

    2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件

    3、增、删、改操作较多的数据库字段不适合建索引
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43746433/article/details/106458200