表中不存在键,但它是 | Postgresql, timescaledb

Posted

技术标签:

【中文标题】表中不存在键,但它是 | Postgresql, timescaledb【英文标题】:Key is not present in table, but it is | Postgresql, timescaledb 【发布时间】:2022-01-18 15:04:23 【问题描述】:

我有下一个数据库。

CREATE TABLE DataLines(
    id        BIGSERIAL NOT NULL,
    TimeStamp TIMESTAMP NOT NULL,
    
    PRIMARY KEY (id, timestamp)
);

CREATE TABLE SpnValues(
    id         BIGSERIAL NOT NULL PRIMARY KEY                              ,
    valueInt   BIGINT    NOT NULL                                          ,
    dataLineId BIGSERIAL                                                   ,
    timestamp  TIMESTAMP NOT NULL                                          ,
    
    FOREIGN KEY (datalineid, timestamp) REFERENCES DataLines(id, timestamp)
);

当我尝试在其中插入一些值时,我收到一个错误“表中不存在键”,但确实如此,我已经检查过了!我什至尝试直接从datalines 写信给spnvalues,但收到同样的错误。

有什么问题?

UPD

我从DataLines 创建超表。

SELECT create_hypertable('datalines', 'timestamp');

【问题讨论】:

哪个 Postgresql 版本?它适用于版本 9.5 到 14。dbfiddle.uk/… 时间戳的精度高达微秒。您尝试在spnvalues 中插入的值很可能与datalines 中的值略有不同。一般来说,我认为向主键添加 timestamp 值是有意义的。特别是如果您已经生成了主键(顺便说一句:don't use serial) @jarlh,现在是 14。 @a_horse_with_no_name , idk,我尝试通过 SELECT timestamp FROM Datalines 插入,但没有成功。 请包含重现错误所需的插入语句。 【参考方案1】:

Foreign key constraints referencing a hypertable are not supported.

我尝试了独特的约束,但也没有成功。

所以,我解决这个问题的唯一方法是删除 SpnValues 中的 foregein 键

CREATE TABLE SpnValues(
    id         BIGSERIAL NOT NULL PRIMARY KEY,
    valueInt   BIGINT    NOT NULL            ,
    dataLineId BIGSERIAL NOT NULL            ,
    timestamp  TIMESTAMP NOT NULL
);

旧版本

datalineid 也必须是NOT NULL,与timestamp 相同。

CREATE TABLE SpnValues(
    id         BIGSERIAL NOT NULL PRIMARY KEY                              ,
    valueInt   BIGINT    NOT NULL                                          ,
    dataLineId BIGSERIAL NOT NULL                                          ,
    timestamp  TIMESTAMP NOT NULL                                          ,

    FOREIGN KEY (datalineid, timestamp) REFERENCES DataLines(id, timestamp)
);

【讨论】:

没关系。 @jarlh,不,这很重要,因为我只有在设置 datalineid 不为空时才解决此问题。 Post hoc ergo propter hoc 可能。 @Stefanov.sm ,我忍不住,但承认,你是对的,但我没有更改插入请求,所以如果我发现我犯了错误,我'写在这里。 @Stefanov.sm,啊哈!我发现了问题。 dataLineId NULLNOT NULL 没有区别,直到 DataLines 不是超表。当它是 - 有区别。【参考方案2】:

原因可能是您提供的TimeStamp 值缺乏精度。内部时间戳精确到微秒,即你的值文字必须看起来像这样'2021-12-15 14:19:20.248137'。所以运行下面的查询以提取所有TimeStamp 数字并重试。

select id, to_char(TimeStamp, 'yyyy-mm-dd hh24:mi:ss.us')
from datalines;

样本输出:

id to_char
1 2021-12-15 14:19:20.248137
2 2021-12-14 14:19:20.248137

我试过了

insert into SpnValues (valueInt, dataLineId, TimeStamp) 
  values (10, 2, '2021-12-14 14:19:20.248137');

它有效。以毫秒精度(3 位数)失败。

【讨论】:

以上是关于表中不存在键,但它是 | Postgresql, timescaledb的主要内容,如果未能解决你的问题,请参考以下文章

如何仅从 PostgreSQL 的内部联接中不存在 id 的表中选择行?

错误:PostgreSQL 中不存在列

错误:表中不存在列(外键引用)

表中不存在键列

尝试定义 FOREIGN KEY 时出现“表中不存在键列”

Django 迁移抛出 1072 - 表中不存在键列“car_make_id”