Django和Postgresql出现运算符不存在的问题:integer = character varying

5

我有这两个模型:

class CachedRecord(models.Model):
    recordname = models.CharField(max_length=100,primary_key=True)
    recordcount = models.IntegerField()
    def __unicode__(self):
        return self.recordname

class CachedRecordData(models.Model):
    record = models.ForeignKey(CachedRecord)
    data = models.CharField(max_length=100)
    def __unicode__(self):
        return self.data

当我尝试从管理面板中删除CachedRecord时,我收到了以下错误提示:
ProgrammingError at /admin/myapp/cachedrecord/

operator does not exist: integer = character varying
LINE 1: ...ON ( "myapp_cachedrecorddata"."record_id" = "myapp...
                                                             ^
HINT:  No operator matches the given name and argument type(s).
You might need to add explicit type casts.

我发现了很多问题(所以这可能是一个重复的问题),但我真的不明白任何答案。 heroku, postgreSQL, django, comments, tastypie: 没有匹配给定名称和参数类型的运算符。您可能需要添加显式类型转换 没有匹配给定名称和参数类型的运算符。您可能需要在Netbeans、Postgresql 8.4和Glassfish中添加显式类型转换 在Django中,我需要在哪里添加这些强制转换?
3个回答

9

这个问题已经被问答几年了,但今天我遇到了同样的问题,并发现了被接受的答案,虽然“简单”,但并没有真正解决意外的数据库表类型的根本问题。Django可以很好地“正确管理”用户定义的主键。

我遇到了一个类似的问题:ProgrammingError: operator does not exist: character = uuid

在将我的Django项目的MySQL数据库迁移到PostgreSQL后,我遇到了这个问题。MySQL没有原生UUID字段,因此使用models.UUIDField表示为VARCHAR(32)。迁移后,PostgreSQL中的字段类型也被创建为character(32)。为了解决这个问题,我必须使用PostgreSQL命令行更改字段类型:

ALTER TABLE my_table ALTER COLUMN my_field TYPE uuid USING uuid::uuid;

这将字段类型转换为Django期望找到的PostgreSQL本地UUID类型。

我猜测OP在CachedRecord表已经有CachedRecordData并使用Django默认创建的整数ID字段作为主键之后添加了recordname字段。在将新的recordname字段设置为主键后,OP需要更新现有关系以使用新的主键。


5
您已将字符字段(recordname)设置为CachedRecord的主键。
Django为CachedRecordData创建了一个自动的主键(类型为整数),称为id - 因为在模型定义中没有指定主键。
现在,当您尝试删除CachedRecord时,django会创建一个主键查找以确保删除所有相关的CachedRecordData实例,并且由于其中一个键是字符,另一个键是整数,因此数据库会出现此错误。
解决此问题的最简单方法是从recordname中删除primary_key=True,并让django正确管理键。您始终可以在该列上添加索引或其他约束(例如,设置unique=True)。
这里也有类似的问题:
def __unicode__(self):
    return self.recordname+":"+self.recordcount

您正在将字符串':'self.recordcount相加,这将导致TypeError异常,因为您不能将字符串与数字组合:

>>> ':'+3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

为了解决这个问题:
def __unicode__(self):
    return u'{}:{}'.format(self.recordname, self.recordcount)

2
所以我不能有一个字符串主键吗? - user568021

3
我认为我找到了一个解决方案。我完全理解并尊重其他人在这里关于使用整数字段作为主键的说法,而且默认情况下Django确实是这样做的。因此,如果更改数据库结构是可能的选项,请首先执行该操作!!
但是,如果你像我一样遇到这样的问题,并且使用Django的默认设置对你来说不是一个选项,那么我会更改我的主键字段类型。原本我有:
Username = models.CharField(max_length=1024, primary_key=True, unique=True)

请将此改为TextField!

Username = models.TextField(max_length=1024, primary_key=True, unique=True)

这对我有帮助,我猜想可能是Django尝试将charfield作为主键的结构/索引方式存在错误?我不确定。希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接