2015-05-19 4 views
4

У меня есть следующие отношения между тремя Django моделями:Определение отношения между несколькими моделями - Джанго

class TestCase(models.Model): 
     ''' 
     Define the testcase model. A testcase is a python Class 
     which contains a set of tests 
     ''' 
     name = models.BinaryField(blank=False) 
     filename = models.BinaryField(blank=True) 
     run_flag = models.IntegerField(default=0) 
     run_as_root = models.BooleanField(default=0) 
     num_tests = models.IntegerField(default=0) 
     testsuite = models.ForeignKey(TestSuite) 

     def __str__(self): 
      return self.name 

Пожалуйста, игнорируйте TestSuite: это не важно для этой проблемы. Каждый TestCase - это то, что вы можете себе представить: a TestCase (класс). Таким образом, каждый раз, когда один выполняет TestCase он имеет TestExecution и Result:

class Result(models.Model): 
     ''' 
     Define the result of a testcase. It may be 'PASS', 'FAIL', 
     'SKIPPED' or 'ABORTED' 
     ''' 
     FAIL = 0 
     PASS = 1 
     ABORTED = 2 
     SKIPPED = 3 

     Status = (
      (PASS, 'PASS'), 
      (FAIL, 'FAIL'), 
      (SKIPPED, 'SKIPPED'), 
      (ABORTED, 'ABORTED'), 
     ) 

     status = models.IntegerField(choices=Status, default=FAIL) 

     testcase = models.ForeignKey(TestCase) 


    class TestExecution(models.Model): 

     name = models.BinaryField(blank=False) 
     num_testsuites = models.IntegerField(default=0) 
     time = models.FloatField() 
     date = models.DateTimeField(default=django.utils.timezone.now) 

     result = models.OneToOneField(Result) 

     def __str__(self): 
      return self.name + " : " + self.date + " : " + self.time 

Это может быть сказано, TestCasehasManyResult но отношения между Result и TestExecution является OneToOne. У меня возникли проблемы с моей схемой моделей. Я знаю, что простое решение будет merge таблиц Result и TestExecution:

python manage.py migrate 
Operations to perform: 
    Synchronize unmigrated apps: staticfiles, messages 
    Apply all migrations: admin, autotester, contenttypes, auth, sessions 
Synchronizing apps without migrations: 
    Creating tables... 
    Running deferred SQL... 
    Installing custom SQL... 
Running migrations: 
    Rendering model states... DONE 
    Applying autotester.0005_auto_20150519_1831...Traceback (most recent call last): 
    File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line 
    utility.execute() 
    File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 390, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 441, in execute 
    output = self.handle(*args, **options) 
    File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 221, in handle 
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 110, in migrate 
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 147, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 115, in apply 
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards 
    field, 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/schema.py", line 43, in add_field 
    super(DatabaseSchemaEditor, self).add_field(model, field) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 403, in add_field 
    self.execute(sql, params) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 111, in execute 
    cursor.execute(sql, params) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 79, in execute 
    return super(CursorDebugWrapper, self).execute(sql, params) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 97, in __exit__ 
    six.reraise(dj_exc_type, dj_exc_value, traceback) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 124, in execute 
    return self.cursor.execute(query, args) 
    File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 205, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler 
    raise errorclass, errorvalue 
django.db.utils.IntegrityError: (1062, "Duplicate entry '0' for key 'result_id'") 

Что наиболее подходящий способ продолжить относительно схемы моделей?

Добавление autotester/migrations/0005_auto_20150519_1831.py согласно запросу:

# - - кодирования: UTF-8 - - из будущего импорт unicode_literals

из импортных моделей django.db, миграции

класс миграции (migrations.Migration):

dependencies = [ 
     ('autotester', '0004_auto_20150519_1744'), 
    ] 

    operations = [ 
     migrations.RemoveField(
      model_name='testexecution', 
      name='framework', 
     ), 
     migrations.AddField(
      model_name='testexecution', 
      name='result', 
      field=models.OneToOneField(default=None, to='autotester.Result'), 
      preserve_default=False, 
     ), 
    ]   
+0

Ваша проблема с миграциями? – Charlesthk

+0

Можете ли вы показать нам autotester.0005_auto_20150519_1831? – Charlesthk

+0

@Charlesthk сделано! – cybertextron

ответ

2

A OneToOneField - это как ForeignKey с unique=True.

Проблема связана с этим уникальным ограничением, поскольку вы не можете добавить поле с уникальным ограничением, если ваша база данных не пуста.То, что вы должны сделать, это:

  1. добавить поле без ограничения уникальности = ForeignKey
  2. заполняйте относительно предстоящего уникального ограничения вы будете иметь
  3. Измените ForeignKey к OneToOneField

Проделайте следующие шаги:

Первый шаг:

Удалить файл autotester/migrations/0005_auto_20150519_1831.py и изменить result поле с result = models.ForeignKey(Result, null=True, blank=True) в вашей TestExecution модели и сделать миграцию:

./manage.py makemigrations autotester 
./manage.py migrate autotester 

Второй шаг:

Для каждого Result вас есть, создать TestExecution (замените FOO на соответствующие данные):

results = Result.objects.all() 

for result in results: 
    tst = TestExecution() 
    tst.name = FOO 
    tst. num_testsuites = FOO 
    tst.time = FOO 
    tst.result_id = result.id 
    tst.save() 

Третий шаг

Изменение результата поле с result = models.OneToOneField(Result), а затем выполнить миграцию:

./manage.py makemigrations autotester 
./manage.py migrate autotester 

Вы должны быть хорошо идти.

+0

remove 'result = models.OneToOneField (Result)'? – cybertextron

+0

Я отредактировал мой ответ, чтобы дать вам более подробно – Charlesthk

+0

Удалось ли вам это сделать? – Charlesthk

Смежные вопросы