python - 编程错误 : column "product" is of type product[] but expression is of type text[] enum postgres

标签 python django database postgresql enums

我想保存枚举数组。

我有以下内容:

CREATE TABLE public.campaign
(
  id integer NOT NULL,
  product product[]
)

产品是一个枚举

在 Django 中我是这样定义的:

PRODUCT = (
    ('car', 'car'),
    ('truck', 'truck')
)
class Campaign(models.Model):
    product = ArrayField(models.CharField(null=True, choices=PRODUCT))

但是,当我写下以下内容时:

campaign = Campaign(id=5, product=["car", "truck"])
campaign.save()

我收到以下错误:

ProgrammingError: column "product" is of type product[] but expression is of type text[]
LINE 1: ..."product" = ARRAY['car...

注意 我看到了this回答,但我不使用 sqlalchemy,如果不需要,我宁愿不使用它。

已编辑 我在下面尝试了@Roman Konoval 的建议:

class PRODUCT(Enum):
    CAR = 'car'
    TRUCK = 'truck'

class Campaign(models.Model):
        product = ArrayField(EnumField(PRODUCT, max_length=10))

和:

campaign = Campaign(id=5, product=[CAR, TRUCK])
campaign.save()

但是,我仍然得到同样的错误,

我看到 django 正在将它翻译成字符串列表。 如果我直接在 psql 控制台中写入以下内容:

INSERT INTO campaign ("product") VALUES ('{car,truck}'::product[]) 

一切正常

最佳答案

这里有两个基本问题。

不要使用枚举

如果您继续使用枚举,您在 Stackoverflow 上的下一个问题将是“如何向枚举添加新条目?”。 Django 不支持开箱即用的枚举类型(谢天谢地)。所以你必须为此使用第三方库。您的里程会因图书馆的完整程度而异。

An enum value occupies four bytes on disk. The length of an enum value's textual label is limited by the NAMEDATALEN setting compiled into PostgreSQL; in standard builds this means at most 63 bytes.

如果您认为使用枚举可以节省磁盘空间,以上引自 manual表明这是一种错觉。

查看此 Q&A有关枚举优缺点的更多信息。但总的来说,缺点大于优点。

不要使用数组

Tip: Arrays are not sets; searching for specific array elements can be a sign of database misdesign. Consider using a separate table with a row for each item that would be an array element. This will be easier to search, and is likely to scale better for a large number of elements.

来源:https://www.postgresql.org/docs/9.6/static/arrays.html

如果您要搜索与汽车或卡车有关的广告系列,您将需要做很多艰苦的工作。数据库也是如此。

正确的设计

正确的设计是 postgresql 数组文档页面中建议的设计。创建相关表。这也是标准的 django 方式。

class Campaign(models.Model):
    name = models.CharField(max_length=20)


class Product(Models.model):
    name = models.CharField(max_length=20)
    campaign = models.ForeignKey(Campaign)

这使您的代码更简单。不需要任何额外的存储空间。不需要第三方库。最好的是 django related models 的大量 API对您可用。

关于python - 编程错误 : column "product" is of type product[] but expression is of type text[] enum postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42566034/

相关文章:

python - 值错误: Output of generator should be a tuple `(x, y, sample_weight)` or `(x, y)`

django - 内置的Docker镜像无法达到PostgreSQL

php - 从多列中选择 : codeIgniter

python - Django 和文档文件中的测试

python - 如何使用 Python 制作嵌套 JSON 对象

python - 如何为机器学习模型调整图像大小

Django 模型保存创建者和修改者

python - 如何将 post_save 接收器与 django-polymorphic 一起使用?

java - 关于 Java 中的数据库设计方法的问题

mysql - 获取数据库的最后更新返回 null (mysql)