如何更改 SQLDelight 中表的主键?

Posted

技术标签:

【中文标题】如何更改 SQLDelight 中表的主键?【英文标题】:How to change primary key of table in SQLDelight? 【发布时间】:2020-09-08 00:22:34 【问题描述】:

我们正在做一些项目,我们有 SQLDelight 数据库和 DBRevisionPhrase 表:

CREATE TABLE DbRevisionPhrase (
    userId TEXT NOT NULL,
    phraseId TEXT NOT NULL,
    vocabularyId TEXT NOT NULL, 
    isMissed INTEGER AS Boolean NOT NULL DEFAULT 0,
    countAnswers INTEGER NOT NULL,
    PRIMARY KEY (userId, phraseId, vocabularyId)
);

我们想添加一个新的字段reviewType,并将其添加到PRIMARY KEY,结果是这样的:

import com.baoui.db.ReviewType;

CREATE TABLE DbRevisionPhrase (
    userId TEXT NOT NULL,
    phraseId TEXT NOT NULL,
    vocabularyId TEXT NOT NULL, 
    isMissed INTEGER AS Boolean NOT NULL DEFAULT 0,
    countAnswers INTEGER NOT NULL,
    type TEXT AS ReviewType,
    PRIMARY KEY (userId, phraseId, vocabularyId, type)
);

但是我们也需要迁移,尝试这个我们失败了:

ALTER TABLE DbRevisionPhrase ADD COLUMN type TEXT;
ALTER TABLE DbRevisionPhrase DELETE PRIMARY KEY;
ALTER TABLE DbRevisionPhrase ADD PRIMARY KEY (userId, phraseId, vocabularyId, type);

有错误:

android.database.sqlite.SQLiteException: incomplete input (code 1 SQLITE_ERROR): , while compiling: ALTER TABLE DbRevisionPhrase

我们是否可以以某种方式更改表的主键,或者我们需要删除表,并通过移动所有数据创建新表?

【问题讨论】:

【参考方案1】:

不幸的是,ALTER TABLE 声明无法做到这一点。您将必须创建一个新表并将现有表迁移过来。它看起来像这样:

CREATE TABLE DbRevisionPhrase_new(
  ...
);
INSERT INTO DbRevisionPhrase_new 
SELECT * FROM DbRevisionPhrase;
DROP TABLE DbRevisionPhrase;
ALTER TABLE DbRevisionPhrase_new RENAME TO DbRevisionPhrase;

【讨论】:

以上是关于如何更改 SQLDelight 中表的主键?的主要内容,如果未能解决你的问题,请参考以下文章

如何编写迁移以使用 ManyToManyField 更改模型的主键

修改数据库中表的id

更改数据库行的主键值

访问表中的主键是不是会更改

更改表中一行的主键(id)并将其他行向下移动

数据仓库 ETL 缓慢 - 更改维度中的主键?