Django和Postgresql运算符不存在:整数=字符变化

时间:2015-07-14 11:02:46

标签: python django postgresql

我有这两个模型:

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: No operator matches the given name and argument type(s). You might need to add explicit type casts

No operator matches the given name and argument type(s). You might need to add explicit type casts. -- Netbeans, Postgresql 8.4 and Glassfish

我需要在django中添加这些石头?

3 个答案:

答案 0 :(得分:3)

问/回答了这个问题已有两年了,但是我今天遇到了同样的问题,并找到了可以接受的答案,而“ easy”并没有真正解决数据库表类型意外的根本问题。 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已经在recordname表已经必须使用CachedRecord表添加了CachedRecordData字段之后,使用未定义primary_key的Django默认创建的整数ID字段。在将新的recordname字段添加为主键之后,OP需要更新现有关系以使用新的主键。

答案 1 :(得分:2)

您已将字符字段CachedRecord)设置为CachedRecordData的主键。

Django为名为id的{​​{1}}创建了一个自动主键(类型为整数) - 因为模型定义中没有指定主键。

现在,当您尝试删除CachedRecord时,django正在创建主键查找以确保删除所有相关的CachedRecordData实例,并且因为一个键是一个字符而另一个是整数 - 数据库发出此错误。

解决此问题的最简单方法是从primary_key=True删除recordname并让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 :(得分:0)

我想我为您找到了解决方案。我完全理解并尊重其他人在这里所说的关于使用Integer字段作为主键的说法,默认情况下,这的确是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作为主键构造/索引的方式的错误吗?我不确定。

希望有帮助!