В комнате поместите сущность и создайте заново с обновленными изменениями. - PullRequest
0 голосов
/ 29 мая 2019

Я использую базу данных Room в своем приложении. У меня есть некоторые изменения в столбцах Entity, поэтому в DB Migration я хочу удалить старую таблицу и воссоздать ее с обновленным Entity. Но после запроса Drop Table вместо того, чтобы писать длинный запрос для повторного создания таблицы, можем ли мы просто как-то передать модель сущности или сказать БД о воссоздании сущности? Поскольку в моей сущности есть несколько столбцов, отношений и правило onDelete, запрос будет сложным.

Ниже следует сущность:

@Entity(tableName = MediaTags.TABLE_NAME_UPLOAD_MEDIA,
        foreignKeys =
        @ForeignKey(
                entity = PostUpload.class,
                parentColumns = PostTags.COLUMN_UPLOAD_POST_LOCAL_ID,
                childColumns = MediaTags.COLUMN_UPLOAD_MEDIA_POST_ID,
                onDelete = CASCADE),
        indices = {@Index(MediaTags.COLUMN_UPLOAD_MEDIA_POST_ID)})
public class MediaUpload {
    @Ignore
    public final static int MEDIA_TYPE_IMAGE = 1;
    @Ignore
    public final static int MEDIA_TYPE_VIDEO = 2;

    @PrimaryKey
    @NonNull
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_KEY)
    public String mediaKey; // unique key
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_HASH_MD5)
    public String hashMd5;   // hashMd5 of file, for now we are sending it empty, in future will be used
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_TYPE)
    public int mediaType;  // picture or video
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_STATUS)
    public int status = UploadStatus.NOT_COMPRESSED; // upload and edit statues
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_FILE_PATH)
    public String filePath;
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_POST_ID)
    public String postId;
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_THUMBNAIL)
    public String thumbnail;  // thumbnail in case of videos
    @ColumnInfo(name = MediaTags.COLUMN_UPLOAD_MEDIA_OVERLAY_PATH)
    public String overlayPath;  // overlay image containing all the editing

}

Ответы [ 2 ]

1 голос
/ 29 мая 2019

Я считаю, что вы могли бы использовать следующее: -

private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override

    public void migrate(SupportSQLiteDatabase database) {
            //Create the new table BUT with a different name
            database.execSQL("DROP TABLE IF EXISTS new_mediatags;"); -- just in case but not really required
            database.execSQL("CREATE TABLE new_mediatags (the_column_definitions_you_want)");
            //Copy existing data into the new table (if required)
            database.execSQL("INSERT INTO new_mediatags SELECT the_columns_you_are keeping,null;");
            //Rename the original table
            database.execSQL("ALTER TABLE mediatags RENAME TO old_mediatags;");
            //Rename the new table to the original name
            database.execSQL("ALTER TABLE new_mediatags RENAME TO mediatags;");
            //Drop the renamed original table
            database.execSQL("DROP TABLE IF EXISTS old_mediatags;");
    }
};
  • Это предполагает, что вы хотите сохранить существующие данные, если нет, то просто не копируйте данные.

В качестве примера рассмотрим следующее: -

-- Create the original and load with some data
DROP TABLE If EXISTS mediatags;
CREATE TABLE IF NOT EXISTS mediatags (col1, col2, col3);
INSERT INTO mediatags VALUES('A','B','C'),('D','E','F');
SELECT * FROM mediatags;

-- The code that would be used
DROP TABLE IF EXISTS new_mediatags;
CREATE TABLE IF NOT EXISTS new_mediatags (col1, col3, col4); -- note no col2 but new col added as col4
INSERT INTO new_mediatags SELECT col1,col3,null FROM mediatags; -- copy existing data 
ALTER TABLE mediatags RENAME TO old_mediatags;
ALTER TABLE new_mediatags RENAME TO mediatags;
DROP TABLE old_mediatags;


SELECT * FROM mediatags; -- output the data for the demo

Первые 4 строки просто создают исходную таблицу, загружают ее с некоторыми данными и выводят данные в соответствии с: -

enter image description here

Остальные строки меняют исходную таблицу для новой таблицы, удаляя col2 и добавляя col4, копируя существующие данные (новый столбец будет нулевым, хотя и будет иметь значениеможет быть предоставлено) и, наконец, для демонстрации выводит данные в измененную таблицу в соответствии с: -

enter image description here

0 голосов
/ 29 мая 2019

Если ваша предыдущая версия была 1, а теперь вы хотите обновить ее до версии 2

   INSTANCE = Room.databaseBuilder(context.getApplicationContext(), RoomDatabase.class, databaseName).addMigrations(MIGRATION_1_2).build;

Чтобы добавить столбец

private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        // to delete a column
        database.execSQL("ALTER TABLE atable DROP COLUMN acolumn");
        // to add a new column
        database.execSQL("ALTER TABLE atable ADD COLUMN anewcolumn INTEGER NOT NULL default 0");
    }
};

Конечно, вам нужно использовать новый столбецtype, INTEGER, TEXT и т. д.

Содержимое таблицы останется неизменным, а новый столбец будет инициализирован значением по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...