因此,同时删除 类 及其子 类 时出现 Django 迁移错误,显示为 sql 语法错误,带有 sqlite3

So, I have a Django migrate error when removing classes and their subclasses at the same time, which appears as an sql syntax error, with sqlite3

我在迁移我的模型时遇到错误,我认为这是由于我设置 'limit_choices_to' 包含引号等的方式所致。

Migrations for 'characters':
  0005_auto_20150129_1019.py:
    - Remove field attribute from dicepool
    - Remove field contested_dicepool from dicepool
    - Remove field resisted_by_attribute from dicepool
    - Remove field second_attribute from dicepool
    - Remove field skill from dicepool
    - Remove field arcana from spelldicepool
    - Remove field dicepool_ptr from spelldicepool
    - Delete model DicePool
    - Delete model SpellDicePool
    - Remove field spells from mage
    - Add field contested to spell
    - Add field contested_attribute to spell
    - Add field contested_skill to spell
    - Add field mage to spell
    - Add field resisted to spell
    - Add field resisted_by_attribute to spell
    - Add field rote_attribute to spell
    - Add field rote_skill to spell
PS D:\Django_Projects\nwod_characters> .\manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: autocomplete_light
  Apply all migrations: sessions, admin, auth, characters, contenttypes
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying characters.0005_auto_20150129_1019...Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\django\db\backends\utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python34\lib\site-packages\django\db\backends\sqlite3\base.py", line 485, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: near ")": syntax error

我在右括号附近找不到任何错误,所以我猜这是我的可调用项,但我听从了建议 here

编辑:

实际上,删除可调用对象似乎没有任何效果。这是我的 migration.py 文件:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('characters', '0004_remove_mage_arcana'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='dicepool',
            name='attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='contested_dicepool',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='resisted_by_attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='second_attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='skill',
        ),
        migrations.RemoveField(
            model_name='spelldicepool',
            name='arcana',
        ),
        migrations.RemoveField(
            model_name='spelldicepool',
            name='dicepool_ptr',
        ),
        migrations.DeleteModel(
            name='DicePool',
        ),
        migrations.DeleteModel(
            name='SpellDicePool',
        ),
        migrations.RemoveField(
            model_name='mage',
            name='spells',
        ),
        migrations.AddField(
            model_name='spell',
            name='contested',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='contested_attribute',
            field=models.ForeignKey(related_name='spell_by_contested_attribute', default=None, to='characters.Attribute'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='contested_skill',
            field=models.ForeignKey(related_name='spell_by_contested_skill', default=None, to='characters.Skill'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='mage',
            field=models.ForeignKey(related_name='spell_by_mage', default=None, to='characters.Mage'),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='resisted',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='resisted_by_attribute',
            field=models.ForeignKey(related_name='dice_pools_by_resistance_attribute', default=None, to='characters.Attribute', choices=[('Mental', (('Intelligence', 'Intelligence'), ('Wits', 'Wits'), ('Resolve', 'Resolve'))), ('Physical', (('Strength', 'Strength'), ('Dexterity', 'Dexterity'), ('Stamina', 'Stamina'))), ('Social', (('Presence', 'Presence'), ('Manipulation', 'Manipulation'), ('Composure', 'Composure')))]),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='rote_attribute',
            field=models.ForeignKey(related_name='spell_by_rote_attribute', default=None, to='characters.Attribute', choices=[('Mental', (('Intelligence', 'Intelligence'), ('Wits', 'Wits'), ('Resolve', 'Resolve'))), ('Physical', (('Strength', 'Strength'), ('Dexterity', 'Dexterity'), ('Stamina', 'Stamina'))), ('Social', (('Presence', 'Presence'), ('Manipulation', 'Manipulation'), ('Composure', 'Composure')))]),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='rote_skill',
            field=models.ForeignKey(related_name='spell_by_rote_skill', default=None, to='characters.Skill', choices=[('Mental', (('Academics', 'Academics'), ('Computer', 'Computer'), ('Crafts', 'Crafts'), ('Investigation', 'Investigation'), ('Medicine', 'Medicine'), ('Occult', 'Occult'), ('Politics', 'Politics'), ('Science', 'Science'))), ('Physical', (('Athletics', 'Athletics'), ('Brawl', 'Brawl'), ('Drive', 'Drive'), ('Firearms', 'Firearms'), ('Larceny', 'Larceny'), ('Stealth', 'Stealth'), ('Survival', 'Survival'), ('Weaponry', 'Weaponry'))), ('Social', (('Animal Ken', 'Animal Ken'), ('Empathy', 'Empathy'), ('Expression', 'Expression'), ('Intimidation', 'Intimidation'), ('Persuasion', 'Persuasion'), ('Socialize', 'Socialize'), ('Streetwise', 'Streetwise'), ('Subterfuge', 'Subterfuge')))]),
            preserve_default=False,
        ),
    ]

Django migrate 试图删除相互依赖的字段和 class,即 DicePool 和 SpellDicePool。

我得出这个结论 运行 sqlmigrate

PS D:\Django_Projects\nwod_characters> .\manage.py sqlmigrate characters 0005
.....
  File "C:\Python34\lib\site-packages\django\db\migrations\state.py", line 71, in render
    raise InvalidBasesError("Cannot resolve bases for %r\nThis can happen if you are inheriting models from an app with migrations (e.g. contrib.auth)
\n in an app with no migrations; see https://docs.djangoproject.com/en/1.7/topics/migrations/#dependencies for more" % new_unrendered_models)
django.db.migrations.state.InvalidBasesError: Cannot resolve bases for [<ModelState: 'characters.SpellDicePool'>]
This can happen if you are inheriting models from an app with migrations (e.g. contrib.auth)
 in an app with no migrations; see https://docs.djangoproject.com/en/1.7/topics/migrations/#dependencies for more

我减少了对这个的迁移:

class Migration(migrations.Migration):

    dependencies = [
        ('characters', '0004_remove_mage_arcana'),
    ]

    operations = [
        migrations.DeleteModel(
            name='SpellDicePool',
        ),
        migrations.RemoveField(
            model_name='mage',
            name='spells',
        ),
        migrations.AddField(
            model_name='spell',
            name='contested',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='contested_attribute',
            field=models.ForeignKey(related_name='spell_by_contested_attribute', default=None, to='characters.Attribute'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='contested_skill',
            field=models.ForeignKey(related_name='spell_by_contested_skill', default=None, to='characters.Skill'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='mage',
            field=models.ForeignKey(related_name='spell_by_mage', default=None, to='characters.Mage'),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='resisted',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='spell',
            name='resisted_by_attribute',
            field=models.ForeignKey(related_name='dice_pools_by_resistance_attribute', default=None, to='characters.Attribute', choices=[('Mental', (('Intelligence', 'Intelligence'), ('Wits', 'Wits'), ('Resolve', 'Resolve'))), ('Physical', (('Strength', 'Strength'), ('Dexterity', 'Dexterity'), ('Stamina', 'Stamina'))), ('Social', (('Presence', 'Presence'), ('Manipulation', 'Manipulation'), ('Composure', 'Composure')))]),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='rote_attribute',
            field=models.ForeignKey(related_name='spell_by_rote_attribute', default=None, to='characters.Attribute', choices=[('Mental', (('Intelligence', 'Intelligence'), ('Wits', 'Wits'), ('Resolve', 'Resolve'))), ('Physical', (('Strength', 'Strength'), ('Dexterity', 'Dexterity'), ('Stamina', 'Stamina'))), ('Social', (('Presence', 'Presence'), ('Manipulation', 'Manipulation'), ('Composure', 'Composure')))]),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='spell',
            name='rote_skill',
            field=models.ForeignKey(related_name='spell_by_rote_skill', default=None, to='characters.Skill', choices=[('Mental', (('Academics', 'Academics'), ('Computer', 'Computer'), ('Crafts', 'Crafts'), ('Investigation', 'Investigation'), ('Medicine', 'Medicine'), ('Occult', 'Occult'), ('Politics', 'Politics'), ('Science', 'Science'))), ('Physical', (('Athletics', 'Athletics'), ('Brawl', 'Brawl'), ('Drive', 'Drive'), ('Firearms', 'Firearms'), ('Larceny', 'Larceny'), ('Stealth', 'Stealth'), ('Survival', 'Survival'), ('Weaponry', 'Weaponry'))), ('Social', (('Animal Ken', 'Animal Ken'), ('Empathy', 'Empathy'), ('Expression', 'Expression'), ('Intimidation', 'Intimidation'), ('Persuasion', 'Persuasion'), ('Socialize', 'Socialize'), ('Streetwise', 'Streetwise'), ('Subterfuge', 'Subterfuge')))]),
            preserve_default=False,
        ),
    ]

也就是说我删除了所有 migrations.RemoveField 方法,以及 DicePool 的 migrations.DeleteModel(逻辑上应该先删除)。

然后我 运行 manage.py makemigrations 又得到了这个 migration.py 文件:

class Migration(migrations.Migration):

    dependencies = [
        ('characters', '0005_auto_20150129_1035'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='dicepool',
            name='attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='contested_dicepool',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='resisted_by_attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='second_attribute',
        ),
        migrations.RemoveField(
            model_name='dicepool',
            name='skill',
        ),
        migrations.DeleteModel(
            name='DicePool',
        ),
    ]

这基本上是我从原始 0005 迁移文件中删除的内容。

运行 迁移可以解决所有问题。

如果有人愿意帮我写票,因为这似乎是一个真正的错误,那将不胜感激。