postgresql Django 夹具失败,说明“数据库错误:值太长,类型字符变化(50)”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3803552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-20 00:19:27  来源:igfitidea点击:

Django fixture fails, stating "DatabaseError: value too long for type character varying(50)"

djangopostgresqlutf-8

提问by shanyu

I have a fixture (json) which loads in development environment but fails to do so in server environment. The error says: "DatabaseError: value too long for type character varying(50)"

我有一个在开发环境中加载但在服务器环境中加载失败的夹具 (json)。错误说:“ DatabaseError: value too long for type character varying(50)

My development environment is Windows & Postgres 8.4. The server runs Debian and Postgres 8.3. Database encoding is UTF8 in both systems.

我的开发环境是 Windows & Postgres 8.4。服务器运行 Debian 和 Postgres 8.3。两个系统中的数据库编码都是 UTF8。

It is as if unicode markers in the fixture count as chars on the server and they cause some strings to exceed their field's max length. However that does not happen in the dev environment..

就好像夹具中的 unicode 标记计为服务器上的字符一样,它们会导致某些字符串超过其字段的最大长度。但是,在开发环境中不会发生这种情况。

采纳答案by shanyu

Well, what makes the difference is the encoding of the template databases. On the production server they had ascii encoding while on the dev box it is utf-8.

那么,不同之处在于模板数据库的编码。在生产服务器上,他们使用 ascii 编码,而在开发服务器上使用的是 utf-8。

By default postgres creates a database using the template1. My understanding is that if its encoding is not utf-8, then the database you create will have this issue, even though you create it with utf-8 encoding.

默认情况下,postgres 使用模板 1 创建一个数据库。我的理解是,如果它的编码不是 utf-8,那么即使您使用 utf-8 编码创建它,您创建的数据库也会出现此问题。

Therefore I dropped it and recreated it with its encoding set to UTF8. The snippet below does it (taken from here):

因此我删除了它并重新创建了它的编码设置为 UTF8。下面的代码片段做到了(取自此处):

psql -U postgres 

UPDATE pg_database SET datallowconn = TRUE where datname = 'template0';
\c template0
UPDATE pg_database SET datistemplate = FALSE where datname = 'template1';
drop database template1;
create database template1 with template = template0 encoding = 'UNICODE';
UPDATE pg_database SET datistemplate = TRUE where datname = 'template1';
\c template1
UPDATE pg_database SET datallowconn = FALSE where datname = 'template0';

Now the fixture loads smoothly.

现在夹具加载顺利。

回答by Steve Jalim

Update: the 50 char limit is now 255in Django 1.8

更新:Django 1.8 中的 50 个字符限制现在是 255

--

——

Original answer:

原答案:

I just encountered this this afternoon, too, and I have a fix (of sorts)

我今天下午也刚遇到这个,我有一个修复(各种各样的)

This post hereimplied it's a Django bug to do with length of the value allowed for auth_permission. Further digging backs up that idea, as does this Django ticket(even though it's initially MySQL-related).

此处的这篇文章暗示这是一个 Django 错误,与 auth_permission 允许的值的长度有关。进一步挖掘支持这个想法,这个 Django 票也是如此(即使它最初是与 MySQL 相关的)。

It's basically that a permission name is created based on the verbose_name of a model plus a descriptive permission string, and that can overflow to more than the 50 chars allowed in auth.models.Permission.name.

基本上是基于模型的verbose_name 加上描述性权限字符串创建一个权限名称,并且可以溢出超过auth.models.Permission.name 中允许的50 个字符。

To quote a comment on the Django ticket:

引用对 Django 票的评论:

The longest prefixes for the string value in the column auth_permission.name are "Can change " and "Can delete ", both with 11 characters. The column maximum length is 50 so the maximum length of Meta.verbose_name is 39.

auth_permission.name 列中字符串值的最长前缀为“可以更改”和“可以删除”,均为 11 个字符。列最大长度为 50,因此 Meta.verbose_name 的最大长度为 39。

One solution would be to hack that column to support > 50 characters (ideally via a South migration, I say, so that it's easily repeatable) but the quickest, most reliable fix I could think of was simply to make my extra-long verbose_name definition a lot shorter (from 47 chars in the verbose_name to around 20). All works fine now.

一种解决方案是修改该列以支持 > 50 个字符(我说最好是通过南迁移,这样它很容易重复)但我能想到的最快、最可靠的解决方法就是让我的超长 verbose_name 定义短很多(从verbose_name 中的47 个字符到大约20 个字符)。现在一切正常。

回答by Frank Heikens

Get the real SQL query on both systems and see what is different.

在两个系统上获取真正的 SQL 查询,看看有什么不同。

回答by luc

Just for information : I also had this error

仅供参考:我也有这个错误

DatabaseError: value too long for type character varying(10)

It seems that I was writing data over the limit of 10 for a field. I fixed it by increasing the size of a CharField from 10 to 20

似乎我正在为一个字段写入超过 10 个限制的数据。我通过将 CharField 的大小从 10 增加到 20 来修复它

I hope it helps

我希望它有帮助

回答by geoom

As @stevejalim says, it's quite possible that the column auth_permission.name is the problem with length 50, you verify this with \d+ auth_permission in postgres's shell. In my case this is the problema, thus when I load django models's fixtures I got “DatabaseError: value too long for type character varying(50)”, then change django.contrib.auth's Permission model is complicated, so ... the simple solution was perform a migrate on Permission model, I did this running ALTER TABLE auth_permission ALTER COLUMN name TYPE VARCHAR(100);command in postgres's shell, this works for me.

正如@stevejalim 所说,列 auth_permission.name 很可能是长度为 50 的问题,您可以在 postgres 的 shell 中使用 \d+ auth_permission 验证这一点。就我而言,这就是问题所在,因此当我加载 django 模型的装置时,我得到了“DatabaseError: value too long for type character variables(50)”,然后更改 django.contrib.auth 的 Permission 模型很复杂,所以......简单解决方案是在权限模型上执行迁移,我ALTER TABLE auth_permission ALTER COLUMN name TYPE VARCHAR(100);在 postgres 的 shell中执行了这个运行命令,这对我有用。

credits for this comment

此评论的积分

回答by Missing Semicolon

You can make Django use longer fields for this model by monkey-patching the model prior to using it to create the database tables. In "manage.py", change:

在使用模型创建数据库表之前,您可以通过对模型进行猴子修补,使 Django 为该模型使用更长的字段。在“manage.py”中,更改:

if __name__ == "__main__":
    execute_manager(settings)

to:

到:

from django.contrib.auth.models import Permission
if __name__ == "__main__":
    # Patch the field width to allow for our long model names
    Permission._meta.get_field('name').max_length=200
    Permission._meta.get_field('codename').max_length=200
    execute_manager(settings)

This modifies the options on the field before (say) manage.py syncdbis run, so the databate table has nice wide varchar() fields. You don't need to do this when invoking your app, as you never attempt to modify the Permissions table whle running.

这会在(例如)manage.py syncdb运行之前修改字段上的选项,因此 databate 表具有很好的宽 varchar() 字段。调用应用程序时无需执行此操作,因为在运行时您绝不会尝试修改 Permissions 表。