切换数据库
按需更换,如需更换,建议开发初期就开始切换
Django默认的数据库SQLite
SQLite是一个轻量级的开源免费的数据库。它是一种嵌入式数据库,只是一个.db格式的文件,无需安装,配置和启动。SQLite试图为单独的应用程序和设备提供本地的数据存储。SQLite常见应用场景包括中小型网站,嵌入式设备和应用软件(如android),文件档案管理和桌面程序(exe)文件数据库。SQLite支持多种编程语言(如python)和操作系统(windows, iOS, unix, linux),移植性非常好 。
SQLite不适用以下场景:
客户端/服务器程序
如果你有许多的客户端程序要通过网络访问一个共享的数据库, 你应当考虑用一个客户端/服务器数据库来替代SQLite。 SQLite可以通过网络文件系统工作, 但是因为和大多数网络文件系统都存在延时, 因此执行效率很差。
高流量网站
SQLite通常情况下用作一个中小型网站(日访问次数少于10万)的后台数据库是完全可以胜任的,请不用担心。 但是如果你的网站的访问量大到你开始考虑采取分布式的数据库部署, 那么你应当毫不犹豫的考虑用一个企业级的客户端/服务器数据库来替代SQLite。
超大的数据集
当你在SQLite中开始一个事务处理的时候, 数据库引擎将不得不分配一小块内存(文件缓冲页面)来帮助它自己管理回滚操作。每1MB的数据库文件SQLite需要256字节。对于小型的数据库这些空间不算什么, 但是当数据库增长到数十亿字节的时候, 缓冲页面的尺寸就会相当的大了. 如果你需要存储或修改几十GB的数据, 你应该考虑用其他的数据库引擎。
高并发访问
SQLite对于整个数据库文件进行读取/写入锁定, 这意味着如果任何进程读取了数据库中的某一部分, 其他所有进程都不能再对该数据库的任何部分进行写入操作。 同样的, 如果任何一个进程在对数据库进行写入操作, 其他所有进程都不能再读取该数据库的任何部分。对于大多数情况这不算是什么问题, 在这些情况下每个程序使用数据库的时间都很短暂, 并且不会独占, 这样锁定至多会存在十几毫秒。但是如果有些程序需要高并发, 那么这些程序就需要寻找其他的解决方案了。
切换MySQL数据库
网站部署上线是用MySQL数据库比较多。
MySQL支持高并发的访问,而且相对于SQLite,MySQL性能更好。 如果你需要开发一个高流量或高并发的网站,SQLite将不能满足你的需求。同时,如果你要开发一个Web APP, 不同用户通过网络对数据库进行读写操作,那么SQLite也将不能胜任(比如分布式数据库)。这时我们需要考虑企业级的专业数据库了,比如MySQL。MySQL是最流行的开源免费的关系型数据库,可作为客户端/服务器数据库提供企业级的数据库服务。
安装MySQL
参考:
配置MySQL
创建数据库名和用户名
NAME是数据库名字,需要用命令创建utf8编码数据库
CREATE DATABASE <dbname> CHARACTER SET utf8;
mysql>CREATE DATABASE blog CHARACTER SET utf8;
Query OK, 1 row affected (0.03 sec)
安装 mysqlclient
Windows
目的:关联Python和MySQL
根据官方文档,需要安装mysqlclient
pip install mysqlclient
MacOS
参考:
- https://pypi.org/project/mysqlclient/
- https://www.cnblogs.com/layezi/p/11297933.html
- https://brew.sh/index_zh-cn.html
-
升级setuptools和pip为最新,应该是可选
-
安装Homebrew
-
brew安装
brew install mysql-connector-c
-
brew安装mysql
brew install mysql
-
(Nov 6, 2019 mysqlclient 1.4.5 不需要修改)此时安装mysqlclient已经可以安装成功,但可能存在bug,解决bug需要修改
mysql_config
文件查找
which mysql_config 结果 /usr/local/bin/mysql_config
打开
vi /usr/local/bin/mysql_config
查找修改的地方
/libs="-L$pkglibdir" J
修改
原始 # on macOS, on or about line 112: # Create options libs="-L$pkglibdir" libs="$libs -l " 修改为 # Create options libs="-L$pkglibdir" libs="$libs -lmysqlclient -lssl -lcrypto"
-
安装mysqlclient
pip install mysqlclient
配置settings.py
目的:关联Django和MySQL
源码:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
修改为
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '192.168.1.156',
'PORT': '3306',
# 避免映射数据库时出现警告
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
'charset': 'utf8mb4',
},
}
}
为什么要加上’OPTIONS’呢,因为在后面添加url路由之后访问相关app,会出现如下警告:
WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection ‘default’
HINT: MySQL’s Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you
activate it. See: https://docs.djangoproject.com/en/1.11/ref/databases/#mysql-sql-mode
数据库结构设计
在《Django 开发个人博客02之需求分析》中我们已经了解 这个博客网站需要建立哪些表,每个表中都需要什么字段 ,下面就让我们来进行设计。
在设计之前,需要先补充一下基础知识
-
orm
-
Django模型model中的常用字段
由之前的需求可知,分类和标签需要的数据库字段是相同的,只有id和名称,并且id除特需外,为默认字段并自增,而文章需要的数据库字段相对较多,包括id、标题、摘要、文章内容、封面图片、创建时间、修改时间、文章分类(多对一)、文章标签(多对多)
from django.db import models
# from mdeditor.fields import MDTextField
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=30, verbose_name='文章分类')
class Meta:
verbose_name = '分类'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=30, verbose_name='文章标签')
class Meta:
verbose_name = '标签'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Article(models.Model):
"""
标题、摘要、文章内容、封面图片、创建时间、修改时间、文章分类、文章标签
"""
title = models.CharField(max_length=150, verbose_name='文章标题')
summary = models.TextField(
max_length=230,
default='文章摘要等同于网页description内容,请务必填写...',
verbose_name='文章摘要')
# 文章内容
body = models.TextField(verbose_name='文章内容')
# body = MDTextField()
# img_link = models.CharField(default='/static/images/', max_length=255, blank=True, null=True, verbose_name='图片地址')
# 文章默认缩略图
img_link = models.ImageField(upload_to='images/%Y-%m', max_length=255,
help_text='提示:不添加封面可以不选择图片,默认没有图片',
blank=True, null=True, verbose_name='文章封面')
create_date = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
update_date = models.DateTimeField(verbose_name='修改时间', auto_now=True)
category = models.ForeignKey(Category, verbose_name='文章分类')
tags = models.ManyToManyField(Tag, verbose_name=u'文章标签')
class Meta:
verbose_name = '文章'
verbose_name_plural = verbose_name
ordering = ['-create_date']
def __str__(self):
return self.title
文章缩略图用到了ImageField,故需要安装 python的一个图像处理库 Pillow
pip install Pillow
迁移数据库
迁移数据库分为两种:
- 在开发初期没有进行切换数据库,开发完成后将SQLite数据库内容迁移到MySQL数据库(同切换数据库)
- 已经切换过数据库或者使用原生的SQLite,需要迁移数据库,生成迁移文件
生成迁移文件
关联数据库
# 创建数据库映射迁移文件,该目录下的文件就是数据库要执行的内容,但并没有执行
python manage.py makemigrations
# 执行之前生成的migrations文件,这一步才是操作数据库的第一步
python manage.py migrate
运行项目
python manage.py runserver
删除所有迁移文件(扩展)
此操作只限特殊情况下使用,如为了验证配置settings.py中的OPTIONS配置,不是为了删库跑路
- 删除应用目录下migrations文件夹下所有*_initial.py文件和“pycache”文件夹内的所有文件,如blog/apps/blog/migrations
- 删除数据库中的所有表,如MySQL使用Navicat、sqlyog
- 再次关联数据库,使用makemigrations和migrate命令