【问题标题】:value too long for type character varying(100)----recently switched database, didn't do anything in dbvalue too long for type character varying(100)----最近切换数据库,在db中没有做任何事情
【发布时间】:2016-05-30 10:08:27
【问题描述】:

我最近切换到 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)

【问题讨论】:

  • 你有一个没有预定义长度的 SlugField?将其设置为 255 并迁移
  • 我在您的代码中没有看到任何带有max_length=100 的字段,所以我怀疑您没有显示所有/相关代码。无论如何,问题如下(您可能通过谷歌搜索发现) - 当您在 MySQL 中保存太长的值时,它只会在不告诉您的情况下修剪该值,因此您可以获得残缺的数据。相反,PgSQL 会大声死去。因此,您必须找到哪个字段的限制为 100 个字符,并相应地修剪数据,或者按照上面评论中的@MushahidKhan 建议增加限制
  • @yedpodtrzitko 我没有任何限制为 100 个字符的字段。我会发布我的完整模型
  • 请显示错误回溯
  • @chem1st 我已经添加了回溯......真的希望这个问题得到解决

标签: django postgresql


【解决方案1】:

我认为您不需要帮助来解决这个问题,就像您需要帮助调试它一样。一旦问题清楚,解决方案似乎也很清楚。 Traceback 可能有点不清楚,因为它经历了太多 Django 源代码,它没有告诉你哪个字段有问题。

此问题的背景

首先,我们在保存Post 实例时遇到了问题。好吧,看看模型定义中的所有这些字段:

 ...
  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)

这些可能看起来像文本字段,但其中很多是文本字段的变体,因为如果您考虑一下,您可能不会存储整个文件 在您的数据库中。您将要做的(以及默认情况下 Django 所做的)是将文件存储在某个磁盘上的某个位置,然后在数据库中存储该文件的 path 以便在需要时检索它.

此外,将数据库中的文件路径存储为LongText 或其他可能是一种浪费,因此每个FileField 意味着我们有一个带有max_length 的字段,无论我们是否指定它。因此,上述所有字段都有一个隐含的max_length。实际上,您可以通过阅读 Django 源代码找到这一点。

来源示例

例如,我从未使用过EmbedVideoField,但它原来是a subclass of models.URLField,这意味着如果您不指定set to 200,则默认情况下它有一个max_length

此外,您的各种ImageFields 只是FileFieldwhich has a max_length default of 100 的子类。

以后如何调试这样的问题?

现在,这并不能帮助我们了解您的哪些字段在这种情况下引发了错误。为此,我可能会在代码的某处设置断点,可能在这里:

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

“设置断点”是指:

转到上述模块中的第 65 行 ebagu/main/models.py 并输入以下内容并保存模块:import pdb; pdb.set_trace()

(我自己其实很喜欢ipdb,但这需要Ipython,我也很喜欢...)

运行您的本地服务器,并运行产生此问题的步骤。您最终将提交您的表单,如果您查看启动服务器的控制台,您最终会在第 65 行被转储到一个 shell 中。这个 shell 是 pdb shell,它与普通 shell 有不同的规则,但您可以通过查看实例本身的各个字段 self 并在该方法调用的上下文中运行 Python 代码来评估您即将保存的 Post 实例:

(pdb) len(self.image.path)

使用它,我会手动评估各个字段,并查看哪个字段有这个非常长的条目导致保存窒息(可能是您的 ImageFields 之一)。

带有警告的解决方案

或者,您可以将max_length 添加到所有这些中,但请注意,您很可能需要对您更改的任何有限文本字段执行数据库迁移,因为您的数据库仍在将根据列的定义方式验证输入的长度。 Here's a good StackOverflow answer looking at exactly this problem.

脚注

为什么在您切换到 Postgresql 之前没有出现这种情况?有多种潜在原因,但可能与以前的数据库的设置方式与 Postgresql 数据库的设置方式(手动与 Django 迁移?)有关。

这也可能与您是否更改了这些东西的存储位置有关。您是否更改了 MEDIA 设置以使存储文件的路径变得更长?

您真正应该做的是直接查看您的数据库。打开一个psql 实例并要求它为您描述您的表。它会告诉您哪些字段限制为 100 个字符,哪些字段会给您带来问题。

【讨论】:

  • 感谢您这么晚才回复您,我正要部署我切换到 postgresql 的应用程序,但是我回到 sqlite 的项目遇到了一些问题。如果你有时间,看看stackoverflow.com/questions/35669918/…,我将不胜感激
  • 老实说,我认为您需要一些帮助来调试您的代码。这就是为什么我按照我的方式写这个。让 stackoverflow 调试整个应用程序是行不通的。
  • 是的,这是我的第一个项目,当我阅读您的解决方案时,我在想“他所说的调试是什么意思,到目前为止一切正常”,我听说调试有多重要,但不要这样做掌握。每件事似乎都有效...ofc 这是来自一个菜鸟...
【解决方案2】:

查看数据库。


psql 快速教程

启动 postgres 客户端外壳,例如。与python manage.py dbshell。如下所示:

ebagu=>

线条

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

表明您正在尝试将模型 Post 保存在我认为是应用程序 ma​​in 中。如果您没有在 Post 的 Meta 中更改表格,表格应该类似于 main_post

你想用命令在 postgres shell 中显示所有表:

\d

它将以类似的方式列出表格:

                          List of relations
 Schema |               Name                |     Type      | Owner  
--------+-----------------------------------+---------------+--------
 public | django_migrations                 | table         | hruske
 public | django_migrations_id_seq          | sequence      | hruske
 public | django_session                    | table         | hruske

如果你想查看django_session表的详细信息,你可以这样做:

\d django_session

你会得到这样的结果:

             Table "public.django_session"
    Column    |           Type           | Modifiers 
--------------+--------------------------+-----------
 session_key  | character varying(40)    | not null
 session_data | text                     | not null
 expire_date  | timestamp with time zone | not null
Indexes:
    "django_session_pkey" PRIMARY KEY, btree (session_key)
    "django_session_de54fa62" btree (expire_date)
    "django_session_session_key_461cfeaa630ca218_like" btree (session_key varchar_pattern_ops)

在这里你可以看到哪些字段被定义为varchar(100)

如果想了解更多psql命令,请输入\?

【讨论】:

    【解决方案3】:

    从以前的数据库中删除迁移文件应该可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 2020-04-07
      • 2012-07-03
      • 2011-04-17
      • 2022-11-18
      • 2019-04-22
      • 1970-01-01
      • 1970-01-01
      • 2012-09-07
      相关资源
      最近更新 更多