代码之家  ›  专栏  ›  技术社区  ›  shanyu

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

  •  13
  • shanyu  · 技术社区  · 14 年前

    我有一个fixture(JSON),它在开发环境中加载,但在服务器环境中却失败了。错误显示:“ DatabaseError: value too long for type character varying(50)

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

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

    6 回复  |  直到 9 年前
        1
  •  10
  •   Thibault J    9 年前

    更新:50个字符的限制 is now 255 在Django 1.8

    ——

    原始答案:

    今天下午我也遇到了,我有一个解决办法(差不多)。

    这个 post here 暗示这是一个django错误,与auth_权限允许的值的长度有关。进一步挖掘支持这个想法,就像 this Django ticket (尽管它最初与MySQL相关)。

    基本上,权限名称是基于模型的详细名称加上描述性权限字符串创建的,并且可能溢出到auth.model s.permission.name中允许的50个字符以上。

    引用对Django门票的评论:

    auth_permission.name列中字符串值的最长前缀是“can change”和“can delete”,两者都有11个字符。列的最大长度为50,因此meta.verbose名称的最大长度为39。

    一种解决方案是黑客攻击该列以支持50个字符(我说,最好是通过南部迁移,这样可以很容易地重复),但我能想到的最快、最可靠的解决方案是简单地缩短超长的详细名称定义(从详细名称中的47个字符到大约20个字符)。现在一切正常。

        2
  •  8
  •   shanyu    14 年前

    好吧,区别在于模板数据库的编码。在生产服务器上,他们使用的是ASCII编码,而在dev框上则是UTF-8。

    默认情况下,Postgres使用模板1创建数据库。我的理解是,如果它的编码不是UTF-8,那么您创建的数据库就会有这个问题,即使您使用UTF-8编码创建它。

    因此,我删除了它,并将其编码设置为utf8重新创建了它。下面的代码段是这样做的(摘自 here ):

    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';
    

    现在夹具可以顺利加载。

        3
  •  2
  •   Frank Heikens    14 年前

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

        4
  •  1
  •   luc    12 年前

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

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

    似乎我在为一个字段写超过10个限制的数据。我把一个字符场的大小从10增加到20

    我希望它有帮助。

        5
  •  1
  •   Community Mr_and_Mrs_D    7 年前

    正如@stevejalim所说,列auth-auth-permission.name很可能是长度50的问题,您可以在postgres的shell中使用\d+auth-permission来验证这一点。在我的例子中,这是个问题,因此当我加载django模型的fixture时,我得到了databaseerror:值太长,无法改变类型字符(50),然后更改django.contrib.auth的权限模型很复杂,所以…简单的解决方案是在权限模型上执行迁移,我是在运行 ALTER TABLE auth_permission ALTER COLUMN name TYPE VARCHAR(100); 命令在Postgres的外壳,这对我有效。

    学分 this comment

        6
  •  1
  •   Missing Semicolon    9 年前

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

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

    到:

    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)
    

    这将修改前面字段上的选项(例如) manage.py syncdb 是运行的,因此databate表有很宽的varchar()字段。调用应用程序时不需要这样做,因为您从不尝试修改运行的权限表。