studio - insertar datos en sql server desde android
Confusión: ¿Cómo se comporta SQLiteOpenHelper onUpgrade()? Y junto con la importación de una copia de seguridad de la base de datos de edad? (5)
supongamos que tengo una tabla de base de datos test_table con 2 columnas y un script de creación correspondiente en el SQLiteOpenHelper:
DB_VERSION = 1:
public void onCreate(SQLiteDatabase db)
{
db.execSql("CREATE table test_table (COL_A, COL_B);
}
Esta es la versión inicial de la aplicación 1, que se publica en Play Store.
Después de un tiempo, se actualiza la aplicación y la base de datos utilizada. Supongo que la clase SQLiteOpenHelper tiene que adaptarse así:
DB_VERSION = 2:
public void onCreate(SQLiteDatabase db)
{
db.execSql("CREATE table test_table (COL_A, COL_B, COL_C)");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSql("ALTER TABLE test_table ADD Column COL_C");
}
Después de algún tiempo, otra actualización de la aplicación:
DB_VERSION = 3:
public void onCreate(SQLiteDatabase db)
{
db.execSql("CREATE table test_table (COL_A, COL_B, COL_C, COL_D)");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSql("ALTER TABLE test_table ADD Column COL_D");
}
-> Aquí es donde necesito un consejo. Si el usuario instala la versión 1 de la aplicación, tiene las Columnas A y B. Si luego actualiza a la versión 2, OnUpgrade se activa y agrega una columna C. Los nuevos usuarios que instalan desde cero obtienen las 3 columnas a través de la declaración de creación. Si el usuario se actualiza a la versión 3, onUpgrade se activa de nuevo y se agrega una columna D. Pero, ¿Y SI el usuario instala la versión 1 de la aplicación, luego omite la actualización de la versión 2 y la versión 3? Entonces se habría perdido el
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSql("ALTER TABLE test_table ADD Column COL_C");
}
parte y solo
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSql("ALTER TABLE test_table ADD Column COL_D");
}
sería llamado, lo que lleva a una tabla test_table (COL_A, COL_B, COL_D)?
¿Cuál es la forma correcta de manejar las actualizaciones de la base de datos de una aplicación en vivo, para que el usuario no pierda sus datos? ¿Tiene que verificar todas las versiones posibles (antiguas) en el método onUpgrade () y ejecutar diferentes declaraciones de tabla basadas en esa versión?
Lo pregunto porque en mi aplicación, el usuario tiene la posibilidad de exportar e importar los datos, que no es más que exportar: copie la base de datos completa e importe: reemplace la base de datos de la aplicación con la base de datos de copia de seguridad.
¿Qué sucede si el usuario tiene la versión 1 de la aplicación, exporta la base de datos, actualiza la aplicación (nueva estructura de la base de datos) e importa la copia de seguridad de la versión 1 anterior? -> ¿Cómo se comportará SQLiteOpenHelper? -> ¿Cuál es la forma correcta de manejar las actualizaciones de db junto con la funcionalidad de importación / exportación?
¿Cuál es la forma correcta de manejar las actualizaciones de la base de datos de una aplicación en vivo, para que el usuario no pierda sus datos? ¿Tiene que verificar todas las versiones posibles (antiguas) en el método onUpgrade () y ejecutar diferentes declaraciones de tabla basadas en esa versión?
En general, sí.
Un enfoque común para esto es hacer actualizaciones por pares:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion<2) {
// do upgrade from 1 to 2
}
if (oldVersion<3) {
// do upgrade from 2 to 3, which will also cover 1->3,
// since you just upgraded 1->2
}
// and so on
}
Esto equivale aproximadamente a las migraciones de Rails, por ejemplo.
¿Qué sucede si el usuario tiene la versión 1 de la aplicación, exporta la base de datos, actualiza la aplicación (nueva estructura de la base de datos) e importa la copia de seguridad de la versión 1 anterior? -> ¿Cómo se comportará SQLiteOpenHelper?
Si al "copiar toda la base de datos", literalmente quiere decir una copia completa del archivo de la base de datos SQLite, luego, cuando SQLiteOpenHelper
va a abrir la copia de seguridad restaurada, la base de datos tendrá la versión del esquema anterior y pasará por onUpgrade()
como normal.
¿Cuál es la forma correcta de manejar las actualizaciones de db junto con la funcionalidad de importación / exportación?
Sospecho que la respuesta es: haga su copia de seguridad copiando el archivo completo, o también organice una copia de seguridad y restaure la versión del esquema, que puede obtener llamando a getVersion()
en un objeto SQLiteDatabase
. Dicho esto, no he lidiado mucho con este escenario y puede haber más problemas en los que no estoy pensando.
Creo que es demasiado tarde para responder a esta pregunta, pero puede ayudar a otros.
DB_VERSION = 1:
public void onCreate(SQLiteDatabase db)
{
db.execSql("CREATE table test_table (COL_A, COL_B, COL_C, COL_D, COL_E);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
switch (oldVersion) {
case 1: db.execSql("ALTER TABLE test_table ADD Column COL_C");
db.execSql("ALTER TABLE test_table ADD Column COL_D");
db.execSql("ALTER TABLE test_table ADD Column COL_E");
break;
case 2: db.execSql("ALTER TABLE test_table ADD Column COL_D");
db.execSql("ALTER TABLE test_table ADD Column COL_E");
break;
case 3: db.execSql("ALTER TABLE test_table ADD Column COL_E");
break;
and so on...
}
Si el usuario instala la aplicación por primera vez, obtendrá todas las columnas de onCreate
Si la versión antigua de la base de datos 2 entonces el caso 2 agrega las columnas C y D.
Si la versión antigua de la base de datos 3 entonces el caso 3 agrega solo la columna E
De esa manera no hay confusión acerca de la versión de la base de datos.
Sospecho que también puede crear una nueva tabla con todas las columnas que necesita
CREATE TABLE new_test_table (COL_A, COL_B, COL_C,COL_D);
Copia los datos de la tabla antigua a la nueva.
INSERT INTO new_test_table SELECT * FROM test_table;
soltar la tabla antigua DROP TABLE test_table;
y renombrar la nueva tabla
ALTER TABLE new_test_table RENAME TO test_table;
en resumen
public void onUpgrade(SQLiteDatabase db,int OldVersion,int NewVersion){
db.execSQL("CREATE TABLE new_test_table (COL_A, COL_B, COL_C,COL_D);"+
"INSERT INTO new_test_table SELECT * FROM test_table;"+
"DROP TABLE test_table;"+
"ALTER TABLE new_test_table RENAME TO test_table;");"
}
de esa manera usted no tiene que preocuparse por los cambios de datos o los cambios incrementales
debajo del código psuedo muestra la actualización increamental
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 2:
//upgrade logic from version 2 to 3
case 3:
//upgrade logic from version 3 to 4
case 4:
//upgrade logic from version 4 to 5
break;
default:
throw new IllegalStateException(
"onUpgrade() with unknown oldVersion" + oldVersion));
}
}
Me refiero a la actualización incremental: observe la declaración de interrupción faltante en los casos 2 y 3
diga si la versión anterior es 2 y la nueva es 4, entonces la lógica actualizará la base de datos de 2 a 3 y luego a 4
si la versión anterior es 3 y la nueva es 4, simplemente ejecutará la lógica de actualización de 3 a 4
siga agregando nuevos casos para cada nueva actualización de la versión de la base de datos que hará los cambios increamentales
Android-Database-Upgrade-Tutorial muestra la guía completa de cómo manejar la actualización de su esquema de base de datos de aplicaciones mientras lanza nuevas versiones de aplicaciones.
El tutorial consiste en una aplicación que tiene 4 versiones, cada versión contiene un número diferente de columnas,