簡體   English   中英

./manage.py測試結果在django.db.utils.OperationalError中:沒有這樣的列:MyNewColumn

[英]./manage.py test results in django.db.utils.OperationalError: no such column: MyNewColumn

長話短說:我做了tests.py來覆蓋我的django代碼,我修改了代碼並進行了很多建模(18次遷移),一切正常。

但是在最后一次更改和遷移(添加了一些布爾文件)之后,我的測試在第8次遷移時開始崩潰,

django.db.utils.OperationalError: no such column: tickets_ticket.ActionRequired

在Web站點上的Apache中,我可以使用新列,並在其中添加模型,一切看起來都不錯,但是測試失敗

有人可以告訴我,哪里出了問題以及如何糾正它?


長話說:

Models.py:

def Ticket_generateUniqueID(related=''):
    retval=''
    sanitized=''
......
    # --- now find unique value
    while True:
            passNo += 1
            retval = generateID()
            try:
                    t = Ticket.objects.get(ticket_number=retval)
                    pass
            except ObjectDoesNotExist:
                    return retval
....
class Ticket(models.Model):
....
    ticket_number = models.CharField(max_length=100,default=Ticket_generateUniqueID,help_text=u"ID of ticket")
    ActionRequired = models.BooleanField(default=False,help_text=u"Action Required")
    def save(self):  # {{{
        if not self.id and not self.ticket_number: self.ticket_number=Ticket_generateUniqueID('OTH')
        retval=super(Ticket,self).save()
        return retval

和我的測試會話(應該從沒有test_ *數據庫開始)

$ ./manage.py test -v3
settings ...
Creating test database for alias 'default' (':memory:')...
Operations to perform:
  Synchronize unmigrated apps: django_extensions
  Apply all migrations: admin, tickets, contenttypes, auth, sessions
Synchronizing apps without migrations:
Running pre-migrate handlers for application admin
Running pre-migrate handlers for application auth
Running pre-migrate handlers for application contenttypes
Running pre-migrate handlers for application sessions
Running pre-migrate handlers for application django_extensions
Running pre-migrate handlers for application tickets
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Loading 'initial_data' fixtures...
Checking '/home/gilhad/GIT/kompitech_test/src/kompitech_test' for fixtures...
No fixture 'initial_data' in '/home/gilhad/GIT/kompitech_test/src/kompitech_test'.
Installed 0 object(s) from 0 fixture(s)
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying sessions.0001_initial... OK
  Applying tickets.0001_initial... OK
  Applying tickets.0002_importedemail_is_new... OK
  Applying tickets.0003_auto_20151102_1642... OK
  Applying tickets.0004_auto_20151116_1633... OK
  Applying tickets.0005_auto_20151118_0756... OK
  Applying tickets.0006_emailpart_originalfilename... OK
  Applying tickets.0007_ticket_fv_ticket_id... OK
  Applying tickets.0008_auto_20151123_1430...Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/lib/python2.7/dist-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python2.7/dist-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib/python2.7/dist-packages/django/core/management/commands/test.py", line 50, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/lib/python2.7/dist-packages/django/core/management/commands/test.py", line 71, in execute
    super(Command, self).execute(*args, **options)
  File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python2.7/dist-packages/django/core/management/commands/test.py", line 88, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/lib/python2.7/dist-packages/django/test/runner.py", line 147, in run_tests
    old_config = self.setup_databases()
  File "/usr/lib/python2.7/dist-packages/django/test/runner.py", line 109, in setup_databases
    return setup_databases(self.verbosity, self.interactive, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/test/runner.py", line 299, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/usr/lib/python2.7/dist-packages/django/db/backends/creation.py", line 377, in create_test_db
    test_flush=True,
  File "/usr/lib/python2.7/dist-packages/django/core/management/__init__.py", line 115, in call_command
    return klass.execute(*args, **defaults)
  File "/usr/lib/python2.7/dist-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 161, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/usr/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 68, in migrate
    self.apply_migration(migration, fake=fake)
  File "/usr/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 102, in apply_migration
    migration.apply(project_state, schema_editor)
  File "/usr/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 108, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "/usr/lib/python2.7/dist-packages/django/db/migrations/operations/fields.py", line 139, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/schema.py", line 457, in alter_field
    self._alter_field(model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/sqlite3/schema.py", line 202, in _alter_field
    self._remake_table(model, alter_fields=[(old_field, new_field)])
  File "/usr/lib/python2.7/dist-packages/django/db/backends/sqlite3/schema.py", line 139, in _remake_table
    self.create_model(temp_model)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/schema.py", line 213, in create_model
    definition, extra_params = self.column_sql(model, field)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/schema.py", line 125, in column_sql
    default_value = self.effective_default(field)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/schema.py", line 175, in effective_default
    default = field.get_default()
  File "/usr/lib/python2.7/dist-packages/django/db/models/fields/__init__.py", line 719, in get_default
    return self.default()
  File "/home/gilhad/GIT/kompitech_test/src/kompitech_test/tickets/models.py", line 56, in Ticket_generateUniqueID
    t = Ticket.objects.get(ticket_number=retval)
  File "/usr/lib/python2.7/dist-packages/django/db/models/manager.py", line 92, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 351, in get
    num = len(clone)
  File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 122, in __len__
    self._fetch_all()
  File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 966, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 265, in iterator
    for row in compiler.results_iter():
  File "/usr/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 700, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/usr/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 786, in execute_sql
    cursor.execute(sql, params)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python2.7/dist-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python2.7/dist-packages/django/db/backends/sqlite3/base.py", line 485, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such column: tickets_ticket.ActionRequired

看到,這幾乎不是最后一次遷移,並且每次測試都像以前那樣擴展

$ ls -1 tickets/migrations/*py
tickets/migrations/0001_initial.py
tickets/migrations/0002_importedemail_is_new.py
tickets/migrations/0003_auto_20151102_1642.py
tickets/migrations/0004_auto_20151116_1633.py
tickets/migrations/0005_auto_20151118_0756.py
tickets/migrations/0006_emailpart_originalfilename.py
tickets/migrations/0007_ticket_fv_ticket_id.py
tickets/migrations/0008_auto_20151123_1430.py
tickets/migrations/0009_auto_20151123_1718.py
tickets/migrations/0010_auto_20151123_1928.py
tickets/migrations/0011_auto_20151124_0938.py
tickets/migrations/0012_auto_20151125_1351.py
tickets/migrations/0013_auto_20151125_1406.py
tickets/migrations/0014_configemailcompany.py
tickets/migrations/0015_auto_20151126_1435.py
tickets/migrations/0016_configemailcompany_we.py
tickets/migrations/0017_auto_20151126_1730.py
tickets/migrations/0018_auto_20151127_1103.py
tickets/migrations/0019_auto_20151130_0934.py
tickets/migrations/__init__.py

遷移失敗:

migrations.AlterField(
    model_name='ticket',
    name='by_user',
    field=models.ForeignKey(related_name='changed_records_of_ticket', blank=True, to=settings.AUTH_USER_MODEL, help_text='Last modification was by this user (autofilled)', null=True, db_index=False),
    preserve_default=True,
    ),
migrations.AlterField(
    model_name='ticket',
    name='ticket_number',
    field=models.CharField(default=tickets.models.Ticket_generateUniqueID, help_text='ID of ticket', max_length=100),
    preserve_default=True,
   ),

(以及其他模型中其他by_user的許多其他更改)

問題在於,用於獲取默認值的Ticket_generateUniqueID方法正在嘗試獲取尚未創建遷移的列。

try:
    t = Ticket.objects.get(ticket_number=retval)
    pass
except ObjectDoesNotExist:
    return retval

在這種情況下,我認為您可以通過將方法更改為使用exists()而不是get()來避免此問題。

if Ticket.objects.filter(ticket_number=retval).exists():
    pass
else:
    return retval

如果無法重寫默認方法,則修復起來會比較棘手。 我相信您將必須導致錯誤的遷移之前添加數據遷移,並在那里設置字段值。 在數據遷移中,您可以使用Ticket = apps.get_model('myapp', 'Ticket') 然后,您將能夠運行Ticket.objects.get()而不會出現任何錯誤。

只是一個更新:當我刪除所有遷移並以一個簡單的方式重新創建它們時,我的測試開始失敗:

django.db.utils.OperationalError: no such table: tickets_ticket

當我的測試創建(而不是保存)票證對象之前,向夾具中加載數據,因此我在while周期之前添加了此健全性測試:

if not( u'tickets_ticket' in connection.introspection.table_names()):
    return generateID() # if no table exists, none ID exists too, so anything is unique :)
# --- now find unique value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM