PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

valeur trop longue pour le caractère de type variable (100) ---- base de données récemment changée, n'a rien fait dans la base de données

Je ne pense pas que vous ayez besoin d'aide pour résoudre ce problème, autant que vous avez besoin d'aide pour le déboguer. Une fois que le problème est clair, la solution semble claire aussi. Le Traceback est peut-être un peu flou car il passe par tellement de code source Django et il ne vous dit pas lequel de vos champs a un problème.

Contexte de ce problème

Pour commencer, nous rencontrons des problèmes pour enregistrer un Post exemple. Eh bien, regardez tous ces champs que vous avez dans la définition de votre modèle :

 ...
  url = models.URLField(max_length=250, blank=True, null=True)
  video = EmbedVideoField(verbose_name='link',help_text="Youtube", blank=True, null=True) 
  content = RichTextUploadingField(config_name='default')
  image = models.ImageField(upload_to='images',blank=True, null=True)
  thumbnail = models.ImageField(upload_to='images', blank=True, null=True)

Ceux-ci peuvent ne pas ressembler champs de texte, mais beaucoup d'entre eux sont des variantes des champs de texte car, si vous y réfléchissez, vous n'allez probablement pas stocker des fichiers entiers dans votre base de données. Ce que vous ferez à la place (et ce que fait Django par défaut) est de stocker le fichier quelque part sur un disque, puis dans la base de données, vous stockerez le chemin à ce fichier afin que vous puissiez le récupérer quand vous en avez besoin.

De plus, c'est probablement un gaspillage de stocker les chemins de fichiers dans la base de données en tant que LongText ou autre, donc chaque FileField we have signifie que nous avons un champ avec un max_length que nous le précisions ou non. Ainsi, tous les champs ci-dessus ont un max_length implicite . Vous pouvez en fait le découvrir en lisant le code source de Django.

Exemples de sources

Je n'ai jamais utilisé EmbedVideoField , par exemple, mais il s'avère être une sous-classe de models.URLField , ce qui signifie qu'il a un max_length par défaut défini sur 200 si vous n'en spécifiez pas.

De plus, vos différents ImageField s ne sont que des sous-classes de FileField , qui a un max_length valeur par défaut de 100 .

Comment déboguer des problèmes comme celui-ci à l'avenir ?

Maintenant, cela ne nous aide pas à savoir quel de vos champs génère une erreur dans ce cas. Pour cela, je définirais probablement un point d'arrêt quelque part dans le code, probablement ici :

File "ebagu/main/models.py" in save
   66.       super(Post, self).save(*args, **kwargs)

Par "définir un point d'arrêt", j'entends ce qui suit :

Allez à la ligne 65 dans le module mentionné ci-dessus, ebagu/main/models.py et entrez ce qui suit et enregistrez le module :import pdb; pdb.set_trace()

(En fait, j'ai une forte préférence pour ipdb moi-même, mais cela nécessite Ipython, pour lequel j'ai aussi une forte préférence...)

Exécutez votre serveur local et suivez les étapes à l'origine de ce problème. Vous finirez par soumettre votre formulaire et si vous regardez la console où vous avez démarré votre serveur, vous finirez par être déversé dans un shell juste à la ligne 65. Ce shell est un shell pdb , qui a des règles différentes d'un shell normal, mais vous pouvez évaluer votre Post sur le point d'être enregistré instance, en examinant les différents champs de l'instance elle-même, self , et en exécutant du code Python dans le contexte de cet appel de méthode :

(pdb) len(self.image.path)

En utilisant cela, j'évaluerais manuellement les différents champs et regarderais lequel a cette très longue entrée qui étouffe la sauvegarde (probablement l'un de vos ImageField s).

Solution avec avertissements

Alternativement, vous pouvez simplement ajouter un max_length à tous ces éléments, mais sachez que vous devrez très probablement effectuer des migrations de bases de données pour tout champ de texte limité que vous modifiez, car votre base de données va toujours vérifier la longueur de l'entrée par rapport à la définition de la colonne. Voici une bonne réponse StackOverflow qui examine exactement ce problème .

Note de bas de page

Pourquoi cela n'est-il pas apparu avant que vous ne passiez à Postgresql ? Il existe une variété de raisons potentielles, mais cela a probablement à voir avec la façon dont la base de données précédente a été configurée par rapport à la façon dont la base de données Postgresql a été configurée (manuellement vs migrations Django ?).

Cela peut également avoir à voir avec le fait que vous ayez changé ou non l'emplacement de stockage de ces éléments. Avez-vous changé votre MEDIA paramètres de sorte que les chemins où les fichiers sont stockés sont beaucoup plus longs ?

Ce que vous devriez vraiment faire, c'est regarder directement votre base de données. Ouvrez un psql instance et demandez-lui de décrire vos tables pour vous. Il vous dira quels champs sont limités à 100 caractères et ce sont les champs qui vous posent problème.