South 在尝试迁移时引发 ValueError

Posted

技术标签:

【中文标题】South 在尝试迁移时引发 ValueError【英文标题】:South raises ValueError when trying to migrate 【发布时间】:2013-02-16 14:51:53 【问题描述】:

我直奔主题:South 提出了这个例外:

Microsoft Windows [versão 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Todos os direitos reservados.

C:\Users\Bassut\PycharmProjects\Logos>manage.py migrate api
Running migrations for api:
 - Migrating forwards to 0001_initial.
 > api:0001_initial
FailedDryRun:  ! Error found during dry run of '0001_initial'! Aborting.
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\south-0.7.5-py2.7.egg\south\migration\migr
ators.py", line 175, in _run_migration
    migration_function()
  File "C:\Python27\lib\site-packages\south-0.7.5-py2.7.egg\south\migration\migr
ators.py", line 57, in <lambda>
    return (lambda: direction(orm))
  File "C:\Users\Bassut\PycharmProjects\Logos\migrations\0001_initial.py", line
44, in forwards
    ('course', self.gf('django.db.models.fields.related.ForeignKey')(default=Fal
se, to=orm['api.Course'])),
  File "C:\Python27\lib\site-packages\south-0.7.5-py2.7.egg\south\db\generic.py"
, line 44, in _cache_clear
    return func(self, table, *args, **opts)
  File "C:\Python27\lib\site-packages\south-0.7.5-py2.7.egg\south\db\generic.py"
, line 343, in create_table
    for field_name, field in fields
  File "C:\Python27\lib\site-packages\south-0.7.5-py2.7.egg\south\db\generic.py"
, line 684, in column_sql
    default = field.get_db_prep_save(default, connection=self._get_connection())

  File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
1047, in get_db_prep_save
    connection=connection)
  File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line
 304, in get_db_prep_save
    prepared=False)
  File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py", line
 549, in get_db_prep_value
    value = connection.ops.validate_autopk_value(value)
  File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 28
8, in validate_autopk_value
    raise ValueError('The database backend does not accept 0 as a '
ValueError: The database backend does not accept 0 as a value for AutoField.

C:\Users\Bassut\PycharmProjects\Logos>

models.py:

# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
import datetime

class College(models.Model):
    acronym = models.CharField(max_length=10)
    full_name = models.CharField(max_length=100)

    class Meta():
        db_table = "College"

    def __unicode__(self):
        return self.full_name

class Course(models.Model):
    title = models.CharField(max_length=50)

    class Meta():
        db_table = "Course"

    def __unicode__(self):
        return self.title

class BasicUser(models.Model):
    user = models.ForeignKey(User)
    birthday = models.DateField()

    class Meta():
        db_table = 'BasicUser'

    def __unicode__(self):
        return (self.user.first_name + ' ' + self.user.last_name)

class Administrator(BasicUser):
    def __unicode__(self):
        return self.user.first_name
    class Meta():
        db_table = "Administrator"

class Student(BasicUser):
    college = models.ForeignKey(College, default=False)
    course = models.ForeignKey(Course, default=False)

    def __unicode__(self):
        return self.user.first_name

    class Meta():
        db_table = "Student"

class Subject(models.Model):
    title = models.CharField(max_length=50)

    class Meta():
        db_table = "Subject"

    def __unicode__(self):
        return self.title

class Division(models.Model):
    title = models.CharField(max_length=50)
    subject = models.ForeignKey(Subject)

    class Meta():
        db_table = "Division"

    def __unicode__(self):
        return self.title

class Topic(models.Model):
    division = models.ForeignKey(Division)
    title = models.CharField(max_length=50)

    class Meta():
        db_table = "Topic"

    def __unicode__(self):
        return self.title
    def get_subject(self):
        return self.division.subject

class Material(models.Model):
    topic = models.ForeignKey(Topic)

    added_by = models.ForeignKey(Administrator, verbose_name=u'Who added this material', default=False)
    title = models.CharField(max_length=50)
    text = models.TextField(max_length=5000)

    class Meta():
        db_table = "Material"

    def __unicode__(self):
        return self.title

    def set_subject(self, value):
        self.topic.division.subject = value

    def set_division(self, value):
        self.topic.division = value

class QuestionOption(models.Model):
    description = models.CharField(max_length=5000, verbose_name=u'The question option itself')

    def __unicode__(self):
        return self.description

    class Meta():
        db_table = 'question_option'

class Question(models.Model):
    topic = models.ForeignKey(Topic, verbose_name=u'What that question is about')
    added_by = models.ForeignKey(Administrator, verbose_name=u'Who added this question', default=False)
    difficulty = models.FloatField(default=0)
    type = models.CharField(max_length=30, verbose_name=u'Tipo da questão', default='multichoices')
    college = models.ForeignKey(College, verbose_name=u'From what college is the question')
    year = models.SmallIntegerField(default=datetime.date.today().year)
    text = models.TextField(max_length=30000)
    options = models.ManyToManyField(QuestionOption, related_name='question_alternatives', db_table=u'question_alternatives',
        verbose_name=u'Question alternatives')
    right_one = models.ForeignKey(QuestionOption, verbose_name=u'Right option for this question', default=False)

    class Meta():
        db_table='question'

    def __unicode__(self):
        return self.title

    def mount_question(self):
        return '(' + self.college.acronym + '-' + str(self.year) + ') ' + self.text

另外,0001_initial.py(控制台说明了一些内容):

# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding model 'College'
        db.create_table('College', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('acronym', self.gf('django.db.models.fields.CharField')(max_length=10)),
            ('full_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
        ))
        db.send_create_signal(u'api', ['College'])

        # Adding model 'Course'
        db.create_table('Course', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
        ))
        db.send_create_signal(u'api', ['Course'])

        # Adding model 'BasicUser'
        db.create_table('BasicUser', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
            ('birthday', self.gf('django.db.models.fields.DateField')()),
        ))
        db.send_create_signal(u'api', ['BasicUser'])

        # Adding model 'Administrator'
        db.create_table('Administrator', (
            (u'basicuser_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['api.BasicUser'], unique=True, primary_key=True)),
        ))
        db.send_create_signal(u'api', ['Administrator'])

        # Adding model 'Student'
        db.create_table('Student', (
            (u'basicuser_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['api.BasicUser'], unique=True, primary_key=True)),
            ('college', self.gf('django.db.models.fields.related.ForeignKey')(default=False, to=orm['api.College'])),
            ('course', self.gf('django.db.models.fields.related.ForeignKey')(default=False, to=orm['api.Course'])),
        ))
        db.send_create_signal(u'api', ['Student'])

        # Adding model 'Subject'
        db.create_table('Subject', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
        ))
        db.send_create_signal(u'api', ['Subject'])

        # Adding model 'Division'
        db.create_table('Division', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
            ('subject', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['api.Subject'])),
        ))
        db.send_create_signal(u'api', ['Division'])

        # Adding model 'Topic'
        db.create_table('Topic', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('division', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['api.Division'])),
            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
        ))
        db.send_create_signal(u'api', ['Topic'])

        # Adding model 'Material'
        db.create_table('Material', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('topic', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['api.Topic'])),
            ('added_by', self.gf('django.db.models.fields.related.ForeignKey')(default=False, to=orm['api.Administrator'])),
            ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
            ('text', self.gf('django.db.models.fields.TextField')(max_length=5000)),
        ))
        db.send_create_signal(u'api', ['Material'])

        # Adding model 'QuestionOption'
        db.create_table('question_option', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('description', self.gf('django.db.models.fields.CharField')(max_length=5000)),
        ))
        db.send_create_signal(u'api', ['QuestionOption'])

        # Adding model 'Question'
        db.create_table('question', (
            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('topic', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['api.Topic'])),
            ('added_by', self.gf('django.db.models.fields.related.ForeignKey')(default=False, to=orm['api.Administrator'])),
            ('difficulty', self.gf('django.db.models.fields.FloatField')(default=0)),
            ('type', self.gf('django.db.models.fields.CharField')(default='multichoices', max_length=30)),
            ('college', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['api.College'])),
            ('year', self.gf('django.db.models.fields.SmallIntegerField')(default=2013)),
            ('text', self.gf('django.db.models.fields.TextField')(max_length=30000)),
            ('right_one', self.gf('django.db.models.fields.related.ForeignKey')(default=False, to=orm['api.QuestionOption'])),
        ))
        db.send_create_signal(u'api', ['Question'])

        # Adding M2M table for field options on 'Question'
        db.create_table(u'question_alternatives', (
            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
            ('question', models.ForeignKey(orm[u'api.question'], null=False)),
            ('questionoption', models.ForeignKey(orm[u'api.questionoption'], null=False))
        ))
        db.create_unique(u'question_alternatives', ['question_id', 'questionoption_id'])


    def backwards(self, orm):
        # Deleting model 'College'
        db.delete_table('College')

        # Deleting model 'Course'
        db.delete_table('Course')

        # Deleting model 'BasicUser'
        db.delete_table('BasicUser')

        # Deleting model 'Administrator'
        db.delete_table('Administrator')

        # Deleting model 'Student'
        db.delete_table('Student')

        # Deleting model 'Subject'
        db.delete_table('Subject')

        # Deleting model 'Division'
        db.delete_table('Division')

        # Deleting model 'Topic'
        db.delete_table('Topic')

        # Deleting model 'Material'
        db.delete_table('Material')

        # Deleting model 'QuestionOption'
        db.delete_table('question_option')

        # Deleting model 'Question'
        db.delete_table('question')

        # Removing M2M table for field options on 'Question'
        db.delete_table('question_alternatives')


    models = 
        u'api.administrator': 
            'Meta': 'object_name': 'Administrator', 'db_table': "'Administrator'", '_ormbases': [u'api.BasicUser'],
            u'basicuser_ptr': ('django.db.models.fields.related.OneToOneField', [], 'to': u"orm['api.BasicUser']", 'unique': 'True', 'primary_key': 'True')
        ,
        u'api.basicuser': 
            'Meta': 'object_name': 'BasicUser', 'db_table': "'BasicUser'",
            'birthday': ('django.db.models.fields.DateField', [], ),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'user': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['auth.User']")
        ,
        u'api.college': 
            'Meta': 'object_name': 'College', 'db_table': "'College'",
            'acronym': ('django.db.models.fields.CharField', [], 'max_length': '10'),
            'full_name': ('django.db.models.fields.CharField', [], 'max_length': '100'),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True')
        ,
        u'api.course': 
            'Meta': 'object_name': 'Course', 'db_table': "'Course'",
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'title': ('django.db.models.fields.CharField', [], 'max_length': '50')
        ,
        u'api.division': 
            'Meta': 'object_name': 'Division', 'db_table': "'Division'",
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'subject': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['api.Subject']"),
            'title': ('django.db.models.fields.CharField', [], 'max_length': '50')
        ,
        u'api.material': 
            'Meta': 'object_name': 'Material', 'db_table': "'Material'",
            'added_by': ('django.db.models.fields.related.ForeignKey', [], 'default': 'False', 'to': u"orm['api.Administrator']"),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'text': ('django.db.models.fields.TextField', [], 'max_length': '5000'),
            'title': ('django.db.models.fields.CharField', [], 'max_length': '50'),
            'topic': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['api.Topic']")
        ,
        u'api.question': 
            'Meta': 'object_name': 'Question', 'db_table': "'question'",
            'added_by': ('django.db.models.fields.related.ForeignKey', [], 'default': 'False', 'to': u"orm['api.Administrator']"),
            'college': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['api.College']"),
            'difficulty': ('django.db.models.fields.FloatField', [], 'default': '0'),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'options': ('django.db.models.fields.related.ManyToManyField', [], 'related_name': "'question_alternatives'", 'symmetrical': 'False', 'db_table': "u'question_alternatives'", 'to': u"orm['api.QuestionOption']"),
            'right_one': ('django.db.models.fields.related.ForeignKey', [], 'default': 'False', 'to': u"orm['api.QuestionOption']"),
            'text': ('django.db.models.fields.TextField', [], 'max_length': '30000'),
            'topic': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['api.Topic']"),
            'type': ('django.db.models.fields.CharField', [], 'default': "'multichoices'", 'max_length': '30'),
            'year': ('django.db.models.fields.SmallIntegerField', [], 'default': '2013')
        ,
        u'api.questionoption': 
            'Meta': 'object_name': 'QuestionOption', 'db_table': "'question_option'",
            'description': ('django.db.models.fields.CharField', [], 'max_length': '5000'),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True')
        ,
        u'api.student': 
            'Meta': 'object_name': 'Student', 'db_table': "'Student'", '_ormbases': [u'api.BasicUser'],
            u'basicuser_ptr': ('django.db.models.fields.related.OneToOneField', [], 'to': u"orm['api.BasicUser']", 'unique': 'True', 'primary_key': 'True'),
            'college': ('django.db.models.fields.related.ForeignKey', [], 'default': 'False', 'to': u"orm['api.College']"),
            'course': ('django.db.models.fields.related.ForeignKey', [], 'default': 'False', 'to': u"orm['api.Course']")
        ,
        u'api.subject': 
            'Meta': 'object_name': 'Subject', 'db_table': "'Subject'",
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'title': ('django.db.models.fields.CharField', [], 'max_length': '50')
        ,
        u'api.topic': 
            'Meta': 'object_name': 'Topic', 'db_table': "'Topic'",
            'division': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['api.Division']"),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'title': ('django.db.models.fields.CharField', [], 'max_length': '50')
        ,
        u'auth.group': 
            'Meta': 'object_name': 'Group',
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'name': ('django.db.models.fields.CharField', [], 'unique': 'True', 'max_length': '80'),
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], 'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True')
        ,
        u'auth.permission': 
            'Meta': 'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission',
            'codename': ('django.db.models.fields.CharField', [], 'max_length': '100'),
            'content_type': ('django.db.models.fields.related.ForeignKey', [], 'to': u"orm['contenttypes.ContentType']"),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'name': ('django.db.models.fields.CharField', [], 'max_length': '50')
        ,
        u'auth.user': 
            'Meta': 'object_name': 'User',
            'date_joined': ('django.db.models.fields.DateTimeField', [], 'default': 'datetime.datetime.now'),
            'email': ('django.db.models.fields.EmailField', [], 'max_length': '75', 'blank': 'True'),
            'first_name': ('django.db.models.fields.CharField', [], 'max_length': '30', 'blank': 'True'),
            'groups': ('django.db.models.fields.related.ManyToManyField', [], 'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'),
            u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
            'is_active': ('django.db.models.fields.BooleanField', [], 'default': 'True'),
            'is_staff': ('django.db.models.fields.BooleanField', [], 'default': 'False'),
            'is_superuser': ('django.db.models.fields.BooleanField', [], 'default': 'False'),
        'last_login': ('django.db.models.fields.DateTimeField', [], 'default': 'datetime.datetime.now'),
        'last_name': ('django.db.models.fields.CharField', [], 'max_length': '30', 'blank': 'True'),
        'password': ('django.db.models.fields.CharField', [], 'max_length': '128'),
        'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], 'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'),
        'username': ('django.db.models.fields.CharField', [], 'unique': 'True', 'max_length': '30')
    ,
    u'contenttypes.contenttype': 
        'Meta': 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'",
        'app_label': ('django.db.models.fields.CharField', [], 'max_length': '100'),
        u'id': ('django.db.models.fields.AutoField', [], 'primary_key': 'True'),
        'model': ('django.db.models.fields.CharField', [], 'max_length': '100'),
        'name': ('django.db.models.fields.CharField', [], 'max_length': '100')
    


complete_apps = ['api']

请告诉我发生了什么,以便我解决。

提前致谢!

【问题讨论】:

您使用的是哪个版本的 Django?根据code.djangoproject.com/ticket/17653,看起来这是一个在 1.3 中修复的错误 问题是使用 manage.py syncdb 它工作得很好。但是当我使用南时,它给了我这个错误。 【参考方案1】:

问题是您为Student 定义的ForeignKeys 设置了default=FalseFalseForeignKeys 的无效值。只需删除它们,您就应该很好了。

【讨论】:

是的,我删除了外键字段的所有默认值,它工作得很好。我首先对 FK 使用 default 的原因是,South 不允许我在不指定默认值的情况下添加新列(因为该表中已经存在行)。所以我把它设置为零。谢谢,该帖子将对人们有所帮助!

以上是关于South 在尝试迁移时引发 ValueError的主要内容,如果未能解决你的问题,请参考以下文章

Django 迁移——是不是可以在项目中间使用 South?

django south 在多个数据库上

将 m2m 更改为 char 时,Django South 迁移失败

不知道为啥 django South 试图运行反向迁移

什么是 Django South GhostMigrations 异常以及如何调试它?

ValueError:依赖于没有迁移的应用程序:帐户