Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

test django fini par OperationalError: no such table: xxx

+4 votes

La tête de mon modèle est :

# -*- coding: utf-8 -*-
from django.db import models
from django_th.models.services import Services


class Rss(Services):
"""
    Model for RSS Service
"""
    url = models.URLField(max_length=255)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_rss'

    def __unicode__(self):
        return "%s" % (self.url)

    def show(self):
        return "Services RSS %s %s" % (self.url, self.trigger)

En exécutant un test de mon code j'obtiens :

(django-trigger-happy)foxmask@foxmask:~/Django-VirtualEnv/django-trigger-happy/django_th$ coverage run manage.py test django_th -v2
Creating test database for alias 'default' ('/home/foxmask/Django-VirtualEnv/django-trigger-happy/django_th/trigger_happy_test.sqlite3')...
Destroying old test database 'default'...
Type 'yes' if you would like to try deleting the test database '/home/foxmask/Django-VirtualEnv/django-trigger-happy/django_th/trigger_happy_test.sqlite3', or 'no' to cancel: yes
Operations to perform:
 Synchronize unmigrated apps: debug_toolbar, django_js_reverse
  Apply all migrations: sessions, admin, django_th, th_twitter, auth, contenttypes, th_rss, th_pocket
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying django_th.0001_initial... OK
  Applying sessions.0001_initial... OK
  Applying th_pocket.0001_initial... OK
  Applying th_pocket.0002_auto_20150102_1355... OK
  Applying th_rss.0001_initial... OK
  Applying th_rss.0002_auto_20150102_1355... OK
  Applying th_twitter.0001_initial... OK
  Applying th_twitter.0002_int_to_biginit... OK
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/foxmask/Django-VirtualEnv/django-trigger-happy/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
...
return Database.Cursor.execute(self, query, params)
OperationalError: no such table: django_th_rss

Alors qu'un migrate fait :

(django-trigger-happy)foxmask@foxmask:~/Django-VirtualEnv/django-trigger-happy/django_th$ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: debug_toolbar, django_js_reverse
  Apply all migrations: sessions, admin, django_th, th_twitter, auth, contenttypes, th_rss, th_pocket
Synchronizing apps without migrations:
   Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying django_th.0001_initial... OK
  Applying sessions.0001_initial... OK
  Applying th_pocket.0001_initial... OK
  Applying th_pocket.0002_auto_20150102_1355... OK
  Applying th_rss.0001_initial... OK
  Applying th_rss.0002_auto_20150102_1355... OK
  Applying th_twitter.0001_initial... OK
  Applying th_twitter.0002_int_to_biginit... OK

les scripts de migration :

le 0001 de l'app th_rss incriminée :

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

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('django_th', '__first__'),
    ] 

    operations = [
        migrations.CreateModel(
            name='Rss',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=255)),
                ('status', models.BooleanField(default=False)),
                ('description', models.CharField(max_length=255)),
                ('url', models.URLField(max_length=255)),
                ('trigger', models.ForeignKey(to='django_th.TriggerService')),
            ],
            options={
                'db_table': 'django_th_rss',
            },
            bases=(models.Model,),
        ),
    ]

suivi du 0002

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

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('th_rss', '0001_initial'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='rss',
            name='trigger',
        ),
        migrations.DeleteModel(
            name='Rss',
        ),
    ]

edit : Le settings édulcoré des commentaires : (j'ai atteint la limite des 8000 caractères donc tout n'est pas là)

import os
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ["*"]
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR + '/trigger_happy.sqlite3',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',  
        'PORT': '',  
        'TEST_NAME': BASE_DIR + '/trigger_happy_test.sqlite3',
    }
}

TIME_ZONE = 'Europe/Paris'
LANGUAGE_CODE = 'en'
USE_I18N = True
USE_L10N = True
USE_TZ = True

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
ROOT_URLCONF = 'django_th.urls'
WSGI_APPLICATION = 'django_th.wsgi.application'
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django_th',
    'th_rss',
    'pocket',
    'th_pocket',
    'django_js_reverse',
    'th_evernote',
    'th_twitter',
    'th_readability',
)
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.request'
)
AUTH_PROFILE_MODULE = 'django_th.UserProfile'

Qu'aurai-je pu omettre ?

J'ai fait un test case avec 3 models tout QQ et je n'ai pas de probleme avec l'exécution des TU (tests unitaires) mais là je ne vois pas ce qui le défrise :/

demandé 3-Jan-2015 par foxmask (2,862 points)
edité 9-Jan-2015 par foxmask

Est-ce que tu peux poster les settings de tes base de données (met des étoiles sur le password et l'ip) également ?

2 Réponses

+2 votes
 
Meilleure réponse

Je pense que tu dois migrer ta base au moins une fois car :

$ ./manage.py test
Creating test database for alias 'default'...
Traceback (most recent call last):
...
django.db.utils.OperationalError: no such table: django_th_rss

Par contre :

$ ./manage.py makemigrations
Migrations for 'essai':
  0002_auto_20150103_0645.py:
    - Rename table for city to django_th_rss
$ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: django_extensions
  Apply all migrations: admin, essai, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying essai.0002_auto_20150103_0645... OK
$ ./manage.py test
Creating test database for alias 'default'...

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK
Destroying test database for alias 'default'...
répondu 3-Jan-2015 par Sam (4,980 points)
sélectionné 21-Jan-2015 par foxmask

En fait, le manage.py test créé une base de tests définie dans les settings c'est elle qui n'a pas la table.. Je crois pas avoir vu qu'on pouvait décider sur quelle base on pouvait exécuter le migrates et makemigrations. Je vais vérifier.

Bon alors c'est la big cacaterie ...

le manage.py migrate annonce

Applying th_rss.0001_initial... OK
Applying th_rss.0002_auto_20150102_1355... OK

mais ...

sqlite> .schema django_th_rss
sqlite>

la base sqlite ne contient pas la table ... je deviens fou

alors que

./manage.py sqlmigrate th_rss 0001
BEGIN;
CREATE TABLE "django_th_rss" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL, "status" bool NOT NULL, "description" varchar(255) NOT NULL, "url" varchar(255) NOT NULL, "trigger_id" integer NOT NULL REFERENCES "django_th_triggerservice" ("id"));
CREATE INDEX django_th_rss_b10b1f9f ON "django_th_rss" ("trigger_id");

COMMIT;

donc ca devient logique que les test unitaires ne créent pas non plus la table ...
mais là je ne comprends absolument PLUS RIEN ...

plus rien sur quoi m'appuyer de tangible ...

pour ne rien gater ; j'execute le bout de sql là sur la base sqlite3 et quand je vias pour acceder à la table via un model.save() django me dit qu'elle n'existe pas .... MURPHY DEGAGE DE LA !!!

j'ai trouvé et ca ca fait chier ; p-e un bug django

2 apps avec leur dossier migrations respectifs

en lancant les TU il ne trouve pas la table

je supprime le dossier migrations de la premiere des 2 app et là ca passe ...

alors là c'est du grand n'importe quoi ...

Je penche plutôt pour un conflit de nommage. Tu auras pas le même nom de tables par erreur dans deux modèles ?

Heu non. J'ai une table par app Django . j'aurai dû avoir ce problème plus tôt. Quand j'utilise syncdb ça roule tout seul...

Est-ce que tu auras pas des migrations en conflit avec ton historique de migration ? L'historique, il est est où ?

J'en n'ai plus. J'étais parti pour faire faire un 0001_initial par app via makemigrations , au cas où , pour les prochaines versions, mais vu l'enfer que j'ai eu j'ai abandonné pour me focaliser sur la seule app qui en a eu besoin. Là ça va. C'est stabilisé tant que je n'ai pas besoin de toucher aux modèles du coeur de triggerhappy.
Il faudra que je le regarde plus tard mais j'ai l'impression qu'une fois un folder migration créé Django va voir la dedans le nom de la table du modèle et non plus dans le models.py . En fait je pensais que Django s'appuyait uniquement sur models.py pour ses accès aux données mais avec toutes ces histoires de migrations je n'ai plus du tout cette certitude.

pour clore le sujet je dirai que j'ai fait le makemigration sur la seule dango app qui a subit une modif de modele et là ca suffit.

donc je valide la reponse

je reviendrai plus tard avec des cas tordus ;)

0 votes

Le topic est vieux et a deja reçu une reponse. Mais je poste quand meme la solution que j'ai appliquée pour resoudre ce probleme que moi aussi je viens de rencontrer.

J'ai du modifier mon fichier de settings durant la phase de dev (j'en ai un pour la prod et un pour le dev), et j'ai ajouté ceci a la fin:

class DisableMigrations(object):
  def __contains__(self, item):
    return True

  def __getitem__(self, item):
    return "notmigrations"

MIGRATION_MODULES = DisableMigrations() 

Lachement copié depuis ce gist

Maintenant, si quelqu'un peut m'expliquer plus en details ce qui se passe, ce serait cool. Desactiver les migrations, oui, mais apres le pourquoi...

Je pense egalement qu'il est preferable de desactiver les migrations uniquement durant le test, donc:

if 'test' or 'test_coverage' in sys.argv[1:]:
    MIGRATION_MODULES = DisableMigrations()
répondu 3-Mar-2015 par Nsukami_ (1,998 points)
edité 3-Mar-2015 par Nsukami_
...