Supongamos que tengo una base de datos de habitaciones simple:
@Database(entities = {User.class}, version = 1)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
Ahora, estoy agregando una nueva entidad: Pet
y mejorando la versión a 2:
@Database(entities = {User.class, Pet.class}, version = 2)
abstract class AppDatabase extends RoomDatabase {
public abstract Dao getDao();
}
Por supuesto, Room lanza una excepción: java.lang.IllegalStateException: A migration from 1 to 2 is necessary.
Suponiendo que no he cambiado de User
clase (por lo que todos los datos están seguros), tengo que proporcionar una migración que solo crea una nueva tabla. Entonces, estoy buscando clases generadas por Room, buscando la consulta generada para crear mi nueva tabla, copiándola y pegando en la migración:
final Migration MIGRATION_1_2 =
new Migration(1, 2) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
database.execSQL("CREATE TABLE IF NOT EXISTS `Pet` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))");
}
};
Sin embargo, me resulta inconveniente hacerlo manualmente. ¿Hay alguna manera de decirle a Room? No estoy tocando ninguna de las tablas existentes, por lo que los datos están seguros. ¿Crear una migración para mí?
fuente
Respuestas:
Habitación no no tiene un buen sistema de migración, al menos no hasta
2.1.0-alpha03
.Entonces, hasta que tengamos un mejor sistema de migración, hay algunas soluciones para tener migraciones fáciles en la sala.
Como no existe un método como
@Database(createNewTables = true)
oMigrationSystem.createTable(User::class)
, que debería haber uno u otro, la única forma posible es ejecutardentro de tu
migrate
método.Para obtener el script SQL anterior , tiene 4 formas
1. Escribe tú mismo
Básicamente, debe escribir el script anterior que coincidirá con el script que genera Room. De esta manera es posible, no factible. (Considere que tiene 50 campos)
2. Exportar esquema
Si incluye
exportSchema = true
dentro de su@Database
anotación, Room generará un esquema de base de datos dentro de / esquemas de la carpeta de su proyecto. El uso esAsegúrese de haber incluido las siguientes líneas en
build.grade
el módulo de su aplicaciónCuando ejecute o compile el proyecto, obtendrá un archivo JSON
2.json
, que tiene todas las consultas dentro de su base de datos de Room.Por lo tanto, puede incluir lo anterior
createSql
dentro de sumigrate
método.3. Obtener consulta de AppDatabase_Impl
Si no desea exportar el esquema, aún puede obtener la consulta ejecutando o construyendo el proyecto que generará el
AppDatabase_Impl.java
archivo. y dentro del archivo especificado puede tener.Dentro del
createAllTables
método, habrá scripts de creación de todas las entidades. Puede obtenerlo e incluirlo dentro de sumigrate
método.4. Procesamiento de anotaciones.
Como puede adivinar, Room genera todo lo mencionado anteriormente
schema
yAppDatabase_Impl
archivos dentro del tiempo de compilación y con el procesamiento de anotaciones que agrega conEso significa que también puede hacer lo mismo y crear su propia biblioteca de procesamiento de anotaciones que genera todas las consultas de creación necesarias para usted.
La idea es crear una biblioteca de procesamiento de anotaciones para las anotaciones de habitaciones de
@Entity
y@Database
. Tome una clase con anotaciones,@Entity
por ejemplo. Estos son los pasos que tendrás que seguirStringBuilder
y agregue "CREAR TABLA SI NO EXISTE"class.simplename
o portableName
campo de@Entity
. Agrégalo a tuStringBuilder
@ColumnInfo
anotación. Para cada campo, debe agregar elid INTEGER NOT NULL
estilo de una columna a suStringBuilder
.@PrimaryKey
ForeignKey
yIndices
si existe.Entonces, puedes usarlo como
Hice una biblioteca de este tipo para mí mismo que puede consultar e incluso usarla en su proyecto. Tenga en cuenta que la biblioteca que hice no está llena y solo cumple con mis requisitos para la creación de tablas.
RoomExtension para una mejor migración
Aplicación que usa RoomExtension
Espero que haya sido útil.
ACTUALIZAR
En el momento de escribir esta respuesta, la versión de la sala era
2.1.0-alpha03
y cuando envié un correo electrónico a los desarrolladores recibí una respuesta deDesafortunadamente, todavía nos falta un mejor sistema de migración.
fuente
Lo sentimos, Room no admite la creación automática de tablas sin pérdida de datos.
Es obligatorio escribir la migración. De lo contrario, borrará todos los datos y creará la nueva estructura de tabla.
fuente
Puedes hacerlo de esta manera
El resto será el mismo que ha mencionado anteriormente.
Referencia - Para más
fuente
Puede agregar el siguiente comando gradle a su defaultConfig en su app.gradle:
Cuando ejecute esto, compilará una lista de nombres de tablas con sus declaraciones CREATE TABLE relevantes desde las cuales puede copiar y pegar en sus objetos de migración. Puede que tenga que cambiar los nombres de las tablas.
Por ejemplo, esto es de mi esquema generado:
Y entonces copio y pego la declaración createSql y cambio '$ {TABLE_NAME}' a 'assets' el nombre de la tabla, y listo, las declaraciones de creación de salas generadas automáticamente.
fuente
En este caso, no necesita realizar una migración, puede llamar a .fallbackToDestructiveMigration () cuando esté creando una instancia de base de datos.
Ejemplo:
Y no olvide cambiar la versión de la base de datos.
fuente
¿Quizás en este caso (si solo ha creado una nueva tabla sin cambiar otras) pueda hacer esto sin crear ninguna migración?
fuente