Skip to content

Instantly share code, notes, and snippets.

@luojiyin1987
Last active March 24, 2018 08:43
Show Gist options
  • Save luojiyin1987/c1a571b59ce95bddf2e2d5eba1b4f8ec to your computer and use it in GitHub Desktop.
Save luojiyin1987/c1a571b59ce95bddf2e2d5eba1b4f8ec to your computer and use it in GitHub Desktop.
执行 python3 manage.py migrate 报 django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')

完整报错信息

JoyLegal git:(develop) ✗ python3 manage.py  migrate
Operations to perform:
  Apply all migrations: admin, app, auth, contenttypes, easy_thumbnails, sessions, templated_email
Running migrations:
  Applying app.0037_permissionapplication...Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
    raise errorvalue
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
    res = self._query(query)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 411, in _query
    rowcount = self._do_query(q)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 374, in _do_query
    db.query(q)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 292, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.IntegrityError: (1215, 'Cannot add foreign key constraint')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 355, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 93, in __exit__
    self.execute(sql)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 120, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
    raise errorvalue
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
    res = self._query(query)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 411, in _query
    rowcount = self._do_query(q)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/cursors.py", line 374, in _do_query
    db.query(q)
  File "/usr/local/lib/python3.6/site-packages/MySQLdb/connections.py", line 292, in query
    _mysql.connection.query(self, query)
django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')

在mysql 终端输入SHOW ENGINE INNODB STATUS; 获得

LATEST FOREIGN KEY ERROR
------------------------
2018-03-24 16:04:28 0x700000d51000 Error in foreign key constraint of table joy_legal/#sql-456_b1:
 FOREIGN KEY (`user_id`) REFERENCES `app_user` (`openid`):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html for correct foreign key definition.

0037_permissionapplication.py 内容

# -*- coding: utf-8 -*-
# Generated by Django 1.11.1 on 2018-03-22 04:28
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('app', '0036_auto_20170627_0036'),
    ]

    operations = [
        migrations.CreateModel(
            name='PermissionApplication',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='修改时间')),
                ('grant_homepage_permission', models.BooleanField(default=False, verbose_name='是否申请看首页')),
                ('grant_blog_permission', models.BooleanField(default=False, verbose_name='是否申请看答案')),
                ('grant_post_permission', models.BooleanField(default=False, verbose_name='是否申请看文章')),
                ('grant_question_permission', models.BooleanField(default=False, verbose_name='是否申请进行法律风险筛查')),
                ('grant_problem_permission', models.BooleanField(default=False, verbose_name='是否申请提问')),
                ('process_status', models.CharField(choices=[('0', '处理中'), ('1', '已处理'), ('-1', '删除')], default=0, max_length=1, verbose_name='处理状态')),
                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.User', verbose_name='用户')),
            ],
            options={
                'verbose_name': '申请记录',
                'verbose_name_plural': '申请记录',
            },
        ),
    ]

model.py 内容

# -*- coding: utf-8 -*-
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models
from django.utils.html import format_html

RESPONSE_CHOICES = (
    ('0', '未回复'),
    ('1', '邮件'),
    ('2', '无法成功回复'),
)

QUESTION_CHOICES = (
    ('0', '单选'),
    ('1', '多选'),
)

LOOK_CHOICES = (
    ('0', '文字型'),
    ('1', '图片型'),
)

PROBLEM_SOURCE = (
    ('1', '提问'),
    ('2', '风险筛查'),
)

SEX_CHOICES = (
    ('0', '未知'),
    ('1', '男'),
    ('2', '女'),
)

STATUS_CHOICES = (
    ('0', '处理中'),
    ('1', '已处理'),
    ('-1', '拒绝申请'),
)

class Category(models.Model):
    class Meta:
        verbose_name = '知识分类'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=100, verbose_name='名称')
    image = models.ImageField(upload_to='categories', verbose_name='图标')

    published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class Post(models.Model):
    class Meta:
        verbose_name = '资讯'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=100, verbose_name='标题')
    summary = models.TextField(max_length=255, verbose_name='摘要')
    image = models.ImageField(upload_to='posts', blank=True, null=True, verbose_name='图片')
    content = RichTextUploadingField(verbose_name='内容')

    keywords = models.CharField(default='', blank=True, null=True, max_length=255, verbose_name='搜索关键词')
    categories = models.ManyToManyField(Category, blank=True, verbose_name='所属分类')

    featured = models.BooleanField(default=False, verbose_name='推荐')

    published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class Blog(models.Model):
    class Meta:
        verbose_name = '法律知识问答'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=100, verbose_name='名称')
    content = RichTextUploadingField(verbose_name='内容')

    keywords = models.CharField(default='', blank=True, null=True, max_length=255, verbose_name='搜索关键词')
    categories = models.ManyToManyField(Category, blank=True, verbose_name='所属分类')

    featured = models.BooleanField(default=False, verbose_name='推荐')

    published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class QuestionType(models.Model):
    class Meta:
        verbose_name = '问题分类'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=255, verbose_name='名称')
    weights = models.FloatField(default=1, verbose_name='权重')

    # published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class Question(models.Model):
    class Meta:
        verbose_name = '问题'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=255, verbose_name='题目')
    # number = models.IntegerField(verbose_name='题号')
    type = models.CharField(max_length=1, choices=QUESTION_CHOICES, default=0, verbose_name='题目选择类型')
    look_type = models.CharField(max_length=1, choices=LOOK_CHOICES, default=0, verbose_name='选项外观')
    # parent = models.ForeignKey('self', blank=True, null=True, verbose_name='来源题目')
    # choices = models.CharField(max_length=255, blank=True, null=True, verbose_name='对应选项')
    classification = models.ForeignKey(QuestionType, blank=True, null=True, verbose_name='问题分类')

    published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class Choice(models.Model):
    class Meta:
        verbose_name = '选项'
        verbose_name_plural = verbose_name

    title = models.CharField(max_length=255, verbose_name='选项描述')
    image = models.ImageField(upload_to='choices', blank=True, null=True, verbose_name='选项图片')
    score = models.IntegerField(blank=True, null=True, verbose_name='记分')
    content = RichTextUploadingField(blank=True, null=True, verbose_name='筛查建议')

    question = models.ForeignKey(
        Question, blank=True, null=True, verbose_name='所属题目')
    next_question = models.ForeignKey(
        Question, related_name='next_question', blank=True, null=True, verbose_name='跳转题目')
    blogs = models.ManyToManyField(Blog, verbose_name='知识点')
    # questions = models.ManyToManyField(Question)

    # published = models.BooleanField(default=False, verbose_name='是否发布?')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def __str__(self):
        return self.title


class User(models.Model):
    class Meta:
        verbose_name = '微信用户'
        verbose_name_plural = verbose_name

    openid = models.CharField(max_length=28, verbose_name='OpenID', primary_key=True)
    nickname = models.CharField(max_length=50, blank=True, null=True, verbose_name='昵称')
    sex = models.CharField(max_length=1, choices=SEX_CHOICES, blank=True, null=True, verbose_name='性别')
    city = models.CharField(max_length=50, blank=True, null=True, verbose_name='城市')
    province = models.CharField(max_length=50, blank=True, null=True, verbose_name='省份')
    country = models.CharField(max_length=50, blank=True, null=True, verbose_name='国家')
    headimgurl = models.CharField(max_length=255, blank=True, null=True, verbose_name='头像')

    categories = models.ManyToManyField(Category, blank=True, verbose_name='关注行业')

    # choices = models.ForeignKey(UserChoices, verbose_name='筛查历史')
    active = models.BooleanField(default=True, verbose_name='是否可用?')

    can_view_blog = models.BooleanField(
        default=False, verbose_name='可否浏览问答')
    can_view_post = models.BooleanField(
        default=True, verbose_name='可否浏览文章')
    can_view_question = models.BooleanField(
        default=False, verbose_name='可否进行法律风险筛查')
    can_view_problem = models.BooleanField(
        default=False, verbose_name='可否提问')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def categories_tag(self):
        all_categories = self.categories.values('title')
        if all_categories.count() > 0:
            return format_html('<span>%s</span>' % [category['title'] for category in all_categories])
        else:
            return ''

    categories_tag.short_description = '关注行业'

    def notifications_count(self):
        return self.notification_set.filter(status=False).count()

    notifications_count.short_description = '未读通知数量'

    def headimage_tag(self, width=50, height=50):
        return format_html('<img src="%s" width="%s" height="%s" />' % (self.headimgurl, width, height))

    def headimage_large_tag(self, width=200, height=200):
        return self.headimage_tag(width, height)

    headimage_tag.short_description = '头像预览'

    def post_viewed_count(self):
        return self.browsinghistory_set.filter(post__isnull=False).count()

    post_viewed_count.short_description = '资讯浏览量'

    def blog_viewed_count(self):
        return self.browsinghistory_set.filter(blog__isnull=False).count()

    blog_viewed_count.short_description = '问答浏览量'

    def __str__(self):
        return self.nickname


class Problem(models.Model):
    class Meta:
        verbose_name = '用户疑问'
        verbose_name_plural = verbose_name

    phone = models.CharField(max_length=50, verbose_name='电话')
    email = models.CharField(max_length=255, verbose_name='邮件')
    description = models.TextField(max_length=1000, blank=True, null=True, verbose_name='描述')

    remark = models.TextField(max_length=1000, blank=True, null=True, verbose_name='备注')
    type = models.CharField(max_length=1, choices=PROBLEM_SOURCE, default=1, verbose_name='来源')
    response = models.CharField(max_length=1, choices=RESPONSE_CHOICES, default=0, verbose_name='回复')

    user = models.ForeignKey(User, verbose_name='用户')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    def save(self, **kwargs):
        if self.id:
            past_response = Problem.objects.get(pk=self.id).response
            if past_response[0] is not self.response and self.response is not '0':
                notification = Notification(user=self.user, response=self.response, problem=self)
                notification.save()
                self.user.notification_set.add(notification)
        super(Problem, self).save()

    def __str__(self):
        return self.phone


class Notification(models.Model):
    class Meta:
        verbose_name = '通知'
        verbose_name_plural = verbose_name

    status = models.BooleanField(default=False, verbose_name='是否已阅读')
    response = models.CharField(max_length=1, choices=RESPONSE_CHOICES, default=0, verbose_name='回复方式')

    user = models.ForeignKey(User, verbose_name='提交用户')
    problem = models.ForeignKey(Problem, verbose_name='相关疑问')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')


class UserChoices(models.Model):
    class Meta:
        verbose_name = '用户选题'
        verbose_name_plural = verbose_name

    # TIPS ids 和 user 的组合是唯一的,即同一个 user 只记录同一种选择🌲。
    ids = models.CharField(max_length=255, verbose_name='选择 ID 列表')
    choices = models.ManyToManyField(Choice, verbose_name='选项')
    total = models.FloatField(verbose_name="总分")
    group_scores = models.CharField(max_length=255, blank=True, null=True, verbose_name='分类得分')

    user = models.ForeignKey(User, verbose_name='提交用户')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    def format_choice(self, choice):
        return format_html('<div>%s - %s</div>', choice.question.title, choice.title)

    def format_choices(self):
        _html = [self.format_choice(choice) for choice in self.choices.all()]
        return _html


class BrowsingHistory(models.Model):
    class Meta:
        verbose_name = '浏览记录'
        verbose_name_plural = verbose_name

    user = models.ForeignKey(User, verbose_name='用户')
    post = models.ForeignKey(Post, blank=True, null=True, verbose_name='咨询')
    blog = models.ForeignKey(Blog, blank=True, null=True, verbose_name='问答')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='浏览时间')


class PermissionApplication(models.Model):
    class Meta:
        verbose_name = '申请记录'
        verbose_name_plural = verbose_name

    user = models.ForeignKey(User, verbose_name='用户')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='修改时间')
    grant_homepage_permission = models.BooleanField(
        default=True, verbose_name='是否申请看首页')
    grant_blog_permission = models.BooleanField(
        default=False, verbose_name='是否申请看问答')
    grant_post_permission = models.BooleanField(
        default=False, verbose_name='是否申请看文章')
    grant_question_permission = models.BooleanField(
        default=False, verbose_name='是否申请进行法律风险筛查')
    grant_problem_permission = models.BooleanField(
        default=False, verbose_name='是否申请提问')
    process_status = models.CharField(
        max_length=1, choices=STATUS_CHOICES, default=0, verbose_name='处理状态')

    name = models.CharField(max_length=10, blank=True, null=True, verbose_name='姓名')
    telephone = models.CharField(max_length=11, blank=True, null=True, verbose_name='手机')
    company = models.CharField(max_length=20, blank=True, null=True, verbose_name='单位')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment