Django3.0+Python3.8+MySQL8.0 个人博客搭建七|makemigrations创建数据库的坑(第二弹)

一、理解Django的makemigrationsmigrate

因为前面多次因为makemigrations命令报错,我们来系统的理解一下Django的makemigrationsmigrate命令。

在你改动了 model.py的内容之后执行下面的命令:

python manger.py makemigrations

相当于在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, 但是这个改动还没有作用到数据库文件。

你可以手动打开这个文件,看看里面是什么。当makemigrations之后产生了0001_initial.py 文件,你可以查看下该migrations会对应于什么样子的SQL命令,使用如下命令,

python manger.py sqlmigrate theapp 0001

看到的大概是这样子的:

BEGIN;
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;
 
COMMIT;

makemigrations之后执行命令:

python manager.py migrate

将该改动作用到数据库文件,比如产生table,修改字段的类型等。

二、报错

在做完数据库设计后,在models.py中建表,然后执行makemigrations命令在app下建立 migrations目录。

错误1:No module named ‘markdown’

ModuleNotFoundError: No module named 'markdown'
原因:缺乏markdown模块

实际上,这个错误有点懵,我明明在PyCharm中已经下载了markdown模块,如下:
在这里插入图片描述

解决方案:

尝试在虚拟环境中安装markdown模块:

(fswy) blog xiatian$ pip3 install markdown
Collecting markdown
......
Successfully installed markdown-3.2.1

难道这两块是分开的???
暂时不管吧。

重现输入:$ python3 manage.py makemigrations

错误2:required positional argument: ‘on_delete’

    bigcategory = models.ForeignKey(BigCategory, verbose_name='大分类')
TypeError: __init__() missing 1 required positional argument: 'on_delete'
原因:

django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常。

解决方案:

定义外键的时候需要加上 on_delete=
即:

contract = models.ForeignKey(Contract, on_delete=models.CASCADE)

on_delete各个参数的含义如下:

on_delete=None,               # 删除关联表中的数据时,当前表与其关联的field的行为

on_delete=models.CASCADE,     # 删除关联数据,与之关联也删除

on_delete=models.DO_NOTHING,  # 删除关联数据,什么也不做

on_delete=models.PROTECT,     # 删除关联数据,引发错误ProtectedError

# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)

on_delete=models.SET_NULL,    # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)

# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')

on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)

on_delete=models.SET,         # 删除关联数据,
 
 a. 与之关联的值设置为指定值,设置:models.SET()
 b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
注意:

由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)。

重现输入:$ python3 manage.py makemigrations

错误3:AUTH_USER_MODEL must be of the form ‘app_label.model_name’

raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL must be of the form 'app_label.model_name'
原因:

在settings.py中,AUTH_USER_MODEL=" ",但它必须是'app_label.model_name'类型

解决方案:

在settings.py中

# 作者(网站注册用户)
AUTH_USER_MODEL = 'user.Ouser'
重现输入:$ python3 manage.py makemigrations
(fswy) blog xiatian$ python3 manage.py makemigrations
Migrations for 'fswy':
  fswy/migrations/0002_activate_article_bigcategory_carousel_category_friendlink_keyword_tag.py
    - Create model Activate
    - Create model Article
    - Create model BigCategory
    - Create model Carousel
    - Create model FriendLink
    - Create model Keyword
    - Create model Tag
    - Create model Category
  fswy/migrations/0003_auto_20200424_1819.py
    - Add field author to article
    - Add field category to article
    - Add field keywords to article
    - Add field tags to article
Migrations for 'user':
  user/migrations/0001_initial.py
    - Create model Ouser

终于成功了,执行migrate命令。

(fswy) blog xiatian$ python3 manage.py migrate

错误4:

django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency user.0001_initial on database 'default'.
原因:

如果我们一开始使用的是django原生模型User,在后来的开发中,我们在其他app中想使用自己的User模型,在我们makemigrations时,就会出现以上错误。

解决方法:
一:
  1. 删除除了auth_user表以外的所有数据库
  2. 删除与用户有关app下的migrations文件夹
  3. 重新makemigrations + migrate

缺点:这个方法相当于从头到尾更新重建了我们的数据模型,需要我们备份数据库中的数据

二:
  1. 在setttings文件中注释掉:django.contrib.admin
  2. 在urls文件中注释掉:path(‘admin/’, admin.site.urls)
  3. 重新migrate
  4. 将刚才注释的代码加回去
  5. 重新migrate

这里采取方法二

(fswy)blog xiatian$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: auth, contenttypes, fswy, sessions, user
Running migrations:
  Applying user.0001_initial... OK
  Applying fswy.0002_activate_article_bigcategory_carousel_category_friendlink_keyword_tag... OK
  Applying fswy.0003_auto_20200424_1819... OK
(fswy)blog xiatian$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, fswy, sessions, user
Running migrations:
  No migrations to apply.

在PyCharm中打开Database,刷新,可以看到如图所示:
在这里插入图片描述
即已经将新建的这些表添加到我们的数据库 blog 中了。

原创文章 214 获赞 359 访问量 89万+

猜你喜欢

转载自blog.csdn.net/yxys01/article/details/105738705