如何将 Android 房间列从 notNull=true 更新为 notNull=false?
How do I updated an Android Room column from notNull=true to notNull=false?
问题: 对于 Android Room,它使用预填充的数据库,我似乎无法将 table 列从 notNull=true
到 notNull=false
?预填充的数据库模式是正确的,但我无法获得 Android 房间以正确更新以匹配:
我做了什么: 我编辑了 json 架构文件,删除了特定列的 NOT NULL
,并在 fields
我更新了相同字段的列信息为"notNull": false
。我尝试了一个迁移,不知道它是否正确,使用 ALTER TABLE Notes ADD COLUMN 'QuestionID' INTEGER
并且它实际上再次将 json 文件更新为 NOT NULL
。我似乎找不到有关如何执行此操作的信息? Entity
没有这些注释,我不确定是否有必要在 Entity
中定义这些注释,因为此数据库有其他 table 没有这些注释,并且它们正在通过编译没有问题。我确定这是另一个 80/20 规则,我很愚蠢并且遗漏了一些东西。
json 文件中的示例 Table Question、Quote、Term 和 Deleted 字段需要 notNull=false
并不断改回到 true
... 并且预填充的 table 是正确的。
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`NoteID` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER NOT NULL, `CommentID` INTEGER NOT NULL, `QuestionID` INTEGER NOT NULL, `QuoteID` INTEGER NOT NULL, `TermID` INTEGER NOT NULL, `TopicID` INTEGER NOT NULL, `Deleted` INTEGER NOT NULL, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "noteID",
"columnName": "NoteID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "sourceID",
"columnName": "SourceID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "commentID",
"columnName": "CommentID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "questionID",
"columnName": "QuestionID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "quoteID",
"columnName": "QuoteID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "termID",
"columnName": "TermID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "topicID",
"columnName": "TopicID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "Deleted",
"affinity": "INTEGER",
"notNull": true
}```
json 文件中的架构是基于实体生成的,更改它不会有任何区别。它甚至不是必需的(除非使用 AutoMigration)。
The pre-populated database schema is correct but I cannot get Android Room to update correctly to match:
您必须相应地更改实体或相应地转换预填充的数据库。再次注意实体定义了 Room 的期望。
使用的语言对确切答案很重要。
如果使用 Kotlin,注释可能是:-
data class Note(
@PrimaryKey(autoGenerate = true)
val NoteId: Long,
val SourceID: Long?,
val CommentID: Long?,
val QuestionID: Long?,
val QuoteID: Long?,
val TermID: Long, //<<<<< NOT NULL
val TopicID: Long?,
val Deleted: Long?
)
生成的 java 然后显示 table 创建为 :-
_db.execSQL("CREATE TABLE IF NOT EXISTS `Note` (`NoteId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER, `CommentID` INTEGER, `QuestionID` INTEGER, `QuoteID` INTEGER, `TermID` INTEGER NOT NULL, `TopicID` INTEGER, `Deleted` INTEGER, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )");
即那些长?没有 NOT NULL(TermID 列没有 NULL,因为使用了 Long 而不是 Long?)。
对于 Java,列类型不能是允许 NULL 的原始类型,因为它们必须有一个值并且不能为 null,因此 Room 将派生 NOT NULL。只有对象类型(例如 Long 而不是 long)将被视为允许 NULL。要强制 NOT NULL,则需要使用 @NotNull 注释。
所以 Java 等效项(命名为 Java 注意允许两者都是 used/compiled)可以是:-
@Entity(
foreignKeys = {
@ForeignKey(entity = Source.class,parentColumns = {"SourceID"},childColumns = {"SourceID"}),
@ForeignKey(entity = Comment.class,parentColumns = {"CommentID"},childColumns = {"CommentID"}),
@ForeignKey(entity = Topic.class,parentColumns = {"TopicID"}, childColumns = {"TopicID"})
}
)
class JavaNote {
@PrimaryKey(autoGenerate = true)
long NoteID=0; // primitives cannot be NULL thus imply NOT NULL
Long SourceID;
Long CommentID;
Long QuestionID;
Long QuoteID;
@NotNull
Long TermID; // or long TermID
Long TopicID;
Long Deleted;
}
生成的 java 然后将 table 创建为 :-
_db.execSQL("CREATE TABLE IF NOT EXISTS `JavaNote` (`NoteID` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER, `CommentID` INTEGER, `QuestionID` INTEGER, `QuoteID` INTEGER, `TermID` INTEGER NOT NULL, `TopicID` INTEGER, `Deleted` INTEGER, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )");
- TermID 再次被故意编码为使用 NOT NULL
编译后生成的java可用。
在生成的java(使用Android视图)中发现member/class名称与class注解相同的@Database后缀为_Impl。语句本身在 createAlltables 方法中。
例如:-
问题: 对于 Android Room,它使用预填充的数据库,我似乎无法将 table 列从 notNull=true
到 notNull=false
?预填充的数据库模式是正确的,但我无法获得 Android 房间以正确更新以匹配:
我做了什么: 我编辑了 json 架构文件,删除了特定列的 NOT NULL
,并在 fields
我更新了相同字段的列信息为"notNull": false
。我尝试了一个迁移,不知道它是否正确,使用 ALTER TABLE Notes ADD COLUMN 'QuestionID' INTEGER
并且它实际上再次将 json 文件更新为 NOT NULL
。我似乎找不到有关如何执行此操作的信息? Entity
没有这些注释,我不确定是否有必要在 Entity
中定义这些注释,因为此数据库有其他 table 没有这些注释,并且它们正在通过编译没有问题。我确定这是另一个 80/20 规则,我很愚蠢并且遗漏了一些东西。
json 文件中的示例 Table Question、Quote、Term 和 Deleted 字段需要 notNull=false
并不断改回到 true
... 并且预填充的 table 是正确的。
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`NoteID` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER NOT NULL, `CommentID` INTEGER NOT NULL, `QuestionID` INTEGER NOT NULL, `QuoteID` INTEGER NOT NULL, `TermID` INTEGER NOT NULL, `TopicID` INTEGER NOT NULL, `Deleted` INTEGER NOT NULL, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "noteID",
"columnName": "NoteID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "sourceID",
"columnName": "SourceID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "commentID",
"columnName": "CommentID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "questionID",
"columnName": "QuestionID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "quoteID",
"columnName": "QuoteID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "termID",
"columnName": "TermID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "topicID",
"columnName": "TopicID",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "Deleted",
"affinity": "INTEGER",
"notNull": true
}```
json 文件中的架构是基于实体生成的,更改它不会有任何区别。它甚至不是必需的(除非使用 AutoMigration)。
The pre-populated database schema is correct but I cannot get Android Room to update correctly to match:
您必须相应地更改实体或相应地转换预填充的数据库。再次注意实体定义了 Room 的期望。
使用的语言对确切答案很重要。
如果使用 Kotlin,注释可能是:-
data class Note(
@PrimaryKey(autoGenerate = true)
val NoteId: Long,
val SourceID: Long?,
val CommentID: Long?,
val QuestionID: Long?,
val QuoteID: Long?,
val TermID: Long, //<<<<< NOT NULL
val TopicID: Long?,
val Deleted: Long?
)
生成的 java 然后显示 table 创建为 :-
_db.execSQL("CREATE TABLE IF NOT EXISTS `Note` (`NoteId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER, `CommentID` INTEGER, `QuestionID` INTEGER, `QuoteID` INTEGER, `TermID` INTEGER NOT NULL, `TopicID` INTEGER, `Deleted` INTEGER, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )");
即那些长?没有 NOT NULL(TermID 列没有 NULL,因为使用了 Long 而不是 Long?)。
对于 Java,列类型不能是允许 NULL 的原始类型,因为它们必须有一个值并且不能为 null,因此 Room 将派生 NOT NULL。只有对象类型(例如 Long 而不是 long)将被视为允许 NULL。要强制 NOT NULL,则需要使用 @NotNull 注释。
所以 Java 等效项(命名为 Java 注意允许两者都是 used/compiled)可以是:-
@Entity(
foreignKeys = {
@ForeignKey(entity = Source.class,parentColumns = {"SourceID"},childColumns = {"SourceID"}),
@ForeignKey(entity = Comment.class,parentColumns = {"CommentID"},childColumns = {"CommentID"}),
@ForeignKey(entity = Topic.class,parentColumns = {"TopicID"}, childColumns = {"TopicID"})
}
)
class JavaNote {
@PrimaryKey(autoGenerate = true)
long NoteID=0; // primitives cannot be NULL thus imply NOT NULL
Long SourceID;
Long CommentID;
Long QuestionID;
Long QuoteID;
@NotNull
Long TermID; // or long TermID
Long TopicID;
Long Deleted;
}
生成的 java 然后将 table 创建为 :-
_db.execSQL("CREATE TABLE IF NOT EXISTS `JavaNote` (`NoteID` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `SourceID` INTEGER, `CommentID` INTEGER, `QuestionID` INTEGER, `QuoteID` INTEGER, `TermID` INTEGER NOT NULL, `TopicID` INTEGER, `Deleted` INTEGER, FOREIGN KEY(`SourceID`) REFERENCES `Source`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`CommentID`) REFERENCES `Comment`(`CommentID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`TopicID`) REFERENCES `Topic`(`TopicID`) ON UPDATE NO ACTION ON DELETE NO ACTION )");
- TermID 再次被故意编码为使用 NOT NULL
编译后生成的java可用。 在生成的java(使用Android视图)中发现member/class名称与class注解相同的@Database后缀为_Impl。语句本身在 createAlltables 方法中。
例如:-