我最近切换到postgresql,我认为一切工作正常,直到我意识到当我做后,我得到的值太长的类型字符变化(100)。现在我谷歌它,看到一些类似的问题,但当我尝试一些解决方案,他们没有一个工作。我会解释为什么我的问题是不同的,在我看来。我有这个代码在models.py
class Post(models.Model):
url = models.URLField(max_length=250, blank=True, null=True)
slug = models.CharField(max_length=255, unique=True)
objects = models.Manager()
@property
def save(self, *args, **kwargs):
self.slug = uuslug(self.title, instance=self, max_length=255)
super(Post, self).save(*args, **kwargs)
当我看到一些推荐的解决方案时,我确实尝试过将max_length更改为100。我不知道为什么会发生这种情况,我在db中没有任何内容。我最近切换到了postgresql。你能告诉我为什么会发生这种错误以及我如何修复它吗?我应该远离uuslug吗?
完整模型
.
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
description = models.TextField(verbose_name=('describe'))
author = models.ForeignKey(settings.AUTH_USER_MODEL)
def __unicode__(self):
return self.name
def get_absolute_url(self):
return "/category/%s/" %self.name
def my_handler(sender, instance, created, **kwargs):
action.send(instance.author, verb='following', target=Category)
post_save.connect(my_handler, sender=Category)
class Post(models.Model):
category = models.ForeignKey(Category, verbose_name=('community'))
pub_date = models.DateTimeField(auto_now_add = True)
url = models.URLField(max_length=250, blank=True, null=True)
video = EmbedVideoField(verbose_name='link',help_text="Youtube", blank=True, null=True)
title = models.CharField(max_length = 50)
moderator = models.ForeignKey(User)
views = models.IntegerField(default=0)
slug = models.CharField(max_length=255, unique=True)
objects = models.Manager() # default manager
content = RichTextUploadingField(config_name='default')
rank_score = models.FloatField(default= 1)
image = models.ImageField(upload_to='images',blank=True, null=True)
thumbnail = models.ImageField(upload_to='images', blank=True, null=True)
@property
def domain(self):
long_url = urlparse(self.url).netloc if self.url else "be kind to one another"
return long_url.split('.', 1)[1] if long_url.split('.', 1)[0] == 'www' else long_url
def save(self, *args, **kwargs):
self.slug = uuslug(self.title, instance=self, max_length=255)
super(Post, self).save(*args, **kwargs)
def __unicode__(self):
return self.title
以下是完整的追溯
T型
raceback:
File "env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
34. return bound_func(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
30. return func.__get__(self, type(self))(*args2, **kwargs2)
File "ebagu/main/views.py" in dispatch
191. return super(PostCreateView, self).dispatch(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
249. return super(BaseCreateView, self).post(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
215. return self.form_valid(form)
File "ebagu/main/views.py" in form_valid
186. self.object.save()
File "ebagu/main/models.py" in save
66. super(Post, self).save(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in save
734. force_update=force_update, update_fields=update_fields)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in save_base
762. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
846. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
885. using=using, raw=raw)
File "env/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/db/models/query.py" in _insert
920. return query.get_compiler(using=using).execute_sql(return_id)
File "env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
974. cursor.execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/utils.py" in __exit__
97. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
Exception Type: DataError at /add_post/
Exception Value: value too long for type character varying(100)
4条答案
按热度按时间fkaflof61#
我不认为你需要帮助来解决这个问题,就像你需要帮助来调试它一样。一旦问题清楚了,解决方案似乎也清楚了。Traceback可能有点不清楚,因为它要检查很多Django源代码,而且它没有告诉你哪个字段有问题。
此问题的背景
首先,我们在保存一个
Post
示例时遇到了一些问题,请查看模型定义中的所有字段:这些可能看起来不像文本字段,但它们中的很多都是文本字段的变体,因为如果你仔细想想,你可能不会在数据库中存储整个文件,而是将文件存储在某个磁盘上的某个地方,然后在数据库中存储文件的路径,这样你就可以在需要的时候检索它。
此外,在数据库中将文件路径存储为
LongText
或其他名称可能是一种浪费,因此我们拥有的每一个FileField
都意味着我们拥有一个带有max_length
的字段,无论我们是否指定它。因此,以上所有字段都有一个隐式的max_length
。实际上,你可以通过阅读Django源代码找到这一点。来源示例
例如,我从来没有使用过
EmbedVideoField
,但它是models.URLField
的子类,这意味着如果不指定max_length
,则默认将其设置为200。此外,各种
ImageField
只是FileField
的子类,FileField
的默认值为100。将来如何调试此类问题?
现在,这并不能帮助我们知道在这种情况下,是哪个字段抛出了错误,为此,我可能会在代码中的某个地方设置一个断点,可能在这里:
我所说的“设置断点”,意思如下:
转到上述模块
ebagu/main/models.py
中的第65行,输入以下内容并保存模块:import pdb; pdb.set_trace()
(实际上我自己对ipdb有强烈的偏好,但那需要Ipython,我对它也有强烈的偏好...)
运行您的本地服务器,并运行产生此问题的步骤。您将最终提交表单,如果您查看启动服务器的控制台,您最终将被转储到第65行的shell中。此shell是pdb shell,它具有与普通shell不同的规则,但您可以评估即将保存的
Post
示例,通过查看示例self
上的各个字段,并在该方法调用的上下文中运行Python代码:使用它,我将手动评估各个字段,并查看哪个字段具有阻碍保存的非常长的条目(可能是您的
ImageField
之一)。带警告的解决方案
或者,您可以只向所有这些字段中添加一个
max_length
,但是要预先警告您,您很可能需要对您更改的任何有限文本字段执行数据库迁移,因为您的数据库仍然会根据列的定义方式验证输入的长度。Here's a good StackOverflow answer looking at exactly this problem。脚注
为什么在你切换到Postgresql之前没有出现这个问题?有很多可能的原因,但这可能与以前的数据库是如何设置的以及Postgresql数据库是如何设置的有关(手动迁移还是Django迁移?)
这也可能与你是否改变了这些东西的存储位置有关。你是否改变了你的
MEDIA
设置,使文件存储的路径变长了很多?你真正应该做的是直接查看你的数据库,打开一个
psql
示例,让它为你描述你的表,它会告诉你哪些字段限制在100个字符以内,哪些字段给你带来了问题。cyvaqqii2#
查一下数据库。
快速psql教程
启动postgres客户端shell,例如使用
python manage.py dbshell
。台词
显示您正在尝试将模型Post保存在我假设的appmain中。如果您没有更改Post的 meta中的表,则该表应该类似于
main_post
。您希望使用以下命令在postgres shell中显示所有表:
它将以类似的方式列出表:
如果你想检查表
django_session
的细节,你可以:你会得到这样的结果:
在这里,您可以看到哪些字段定义为
varchar(100)
。如果要了解更多psql命令,请键入
\?
nwwlzxa73#
从以前的数据库中删除迁移文件应该可以解决您的问题。
093gszye4#
该错误是由于数据库中已保存的数据的长度超过了给定的字符数。您可能需要查看该数据并考虑修复它,或者考虑给定的字符数是否确实是您想要的限制。
如果您正在维护模型的历史记录,则还需要删除历史记录表中的数据。