SQLite de Android: reemplaza la base de datos antigua por una nueva o usa scripts de migración

Tengo una aplicación de Android que utiliza una base de datos SQLite y Active Android como ORM. En cada actualización de la aplicación necesito enviar mi base de datos con datos nuevos / actualizados. Esto es lo que he estado haciendo

  1. Tengo una base de datos my_app.db
  2. Hago modificaciones en las filas, tablas, etc. de my_app.db
  3. Guardo el archivo my_app.db modificado como my_app_v2.db (y así sucesivamente)
  4. Reemplazo el archivo my_app.db de la carpeta assets con my_app_v2.db y lo configuro como la base de datos predeterminada
  5. Compilo y ejecuto el programa usando el my_app_v2.db recién creado

Así que cuando el usuario recibe la aplicación, estará utilizando el my_app_v2.db con nuevos contenidos.

Sé que Active Android soporta scripts de migración , pero en cada actualización de la base de datos necesito añadir / actualizar más de 2000 registros. Por lo tanto, para cada actualización de la base de datos necesitaría un script de migración con más de 2000 instrucciones insert / update, significa que para 3 + actualizaciones consecutivas la aplicación tendría que ejecutar más de 6000 declaraciones.

Quiero saber si mi enfoque de reemplazar toda la base de datos por una nueva es una mala práctica y los scripts de migración deben ser preferidos.

Usted no necesita hacer eso (renombrar la materia o cualquier cosa)

Sólo tiene que cambiar la versión de la base de datos y escribir un comando SQL para modificar la tabla anterior para migrar de la versión A a B.

Mira este enlace:

Android: actualizar la versión de la base de datos y agregar nueva tabla

No estoy seguro de que pueda aplicar de esta manera en su aplicación, pero aquí es lo que estoy haciendo para recuperar nuevos datos de otra base de datos.

Para mis aplicaciones, utilizo un sistema de sincronización que comprobará diariamente si hay una nueva base de datos disponible en GoogleDrive (en caso de que el usuario utilice dispositivos diferentes).

Cuando está disponible una nueva copia de seguridad de la base de datos (es decir, tengo que recuperar datos para este dispositivo), recupero la copia de seguridad de la base de datos y la adjunto a la existente mediante:

attach database database/path as new_db 

Entonces apenas ejecuto este comando para cada tabla para poner al día la base de datos existente con los expedientes del que recuperé:

 INSERT OR REPLACE INTO table SELECT * FROM retrieved_database.table 

Por supuesto que va a reemplazar todos los datos existentes, pero de esta manera también manejar los registros que se han modificado. Este método evita el reemplazo completo de la base de datos existente, Acabo de ejecutar una verificación de integridad al final para estar seguro de que todo está bien.

Este método está bien para mí, ya que tengo unas pocas tablas y los datos son ligeros, podría ser una mala idea para bases de datos pesadas.

En mi proyecto, lo usé así

 public class DatabaseHelper extends SQLiteOpenHelper { private final static String TAG = DatabaseHelper.class.getSimpleName(); private static DatabaseHelper sInstance; private Context mContext; private static final String DATABASE_NAME = "xxxx"; private static final String DATABASE_NAME_OLD = "xxxx_old"; private static final int DATABASE_VERSION = 12; private String pathToSaveDBFile, absolutepathToSaveDBFile; private SQLiteDatabase db; private Cursor cursor; public static synchronized DatabaseHelper getInstance(Context mContext) { if (sInstance == null) { sInstance = new DatabaseHelper(mContext); } return sInstance; } /** * initialization constructor * * @param context */ private DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.mContext = context; pathToSaveDBFile = new StringBuffer(context.getFilesDir().getAbsolutePath()).append("/").append(DATABASE_NAME).toString(); absolutepathToSaveDBFile = new StringBuffer(context.getFilesDir().getAbsolutePath()).append("/").append(DATABASE_NAME_OLD).toString(); } /** * prepare database related process * * @throws IOException */ public void prepareDatabase() throws IOException { //boolean dbExist = checkDataBase(); if (checkDataBase()) { Log.d(TAG, "Database exists."); // int currentDBVersion = getVersionId(); if (DATABASE_VERSION > getVersionId()) { Log.d(TAG, "Database version is higher than old."); if (renameDatabase()) { Log.d(TAG, "renameDatabase() "); try { if (copyDataBase()) { deleteDb(); setVersionId(DATABASE_VERSION); } } catch (Exception e) { Log.e(TAG, e.getMessage()); } } } } else { try { /// copy db copyDataBase(); } catch (Exception e) { Log.e(TAG, e.getMessage()); } } } /** * db exist or not? * * @return db checked status */ private boolean checkDataBase() { Log.d(TAG, "checkDataBase()"); boolean checkDB = false; try { File file = new File(pathToSaveDBFile); checkDB = file.exists(); } catch (SQLiteException e) { Log.d(TAG, e.getMessage()); } Log.d(TAG, "checkDataBase: " + checkDB); return checkDB; } /** * db copying * * @return db copy status */ private Boolean copyDataBase() { try { Log.d(TAG, "copyDataBase()"); OutputStream os = new FileOutputStream(pathToSaveDBFile); InputStream is = mContext.getAssets().open("db/" + DATABASE_NAME); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } is.close(); os.flush(); os.close(); return true; } catch (IOException e) { e.getMessage(); return false; } } /** * db renaming * * @return boolean status */ private boolean renameDatabase() { try { Log.d(TAG, "renameDatabase: "); File from = new File(pathToSaveDBFile); File to = new File(absolutepathToSaveDBFile); if (from.renameTo(to)) { return true; } return false; } catch (Exception e) { e.getMessage(); return false; } } /** * * * @return boolen status */ private boolean revertBack_to_OlderName() { try { Log.d(TAG, "renameDatabase: "); File from = new File(absolutepathToSaveDBFile); File to = new File(pathToSaveDBFile); if (from.renameTo(to)) { return true; } return false; } catch (Exception e) { e.getMessage(); return false; } } /** * db deletion * * delete db */ public void deleteDb() { File file = new File(absolutepathToSaveDBFile); if (file.exists()) { file.delete(); Log.d(TAG, "Database deleted."); } } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } @Override public synchronized void close() { db.close(); super.close(); } /** * get db version info * * @return version no */ private int getVersionId() { try { db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READONLY); String query = "SELECT " + AS_DB_VERSION_NUMBER + " FROM " + AS_DB_VERSION_TABLE; cursor = db.rawQuery(query, null); cursor.moveToFirst(); int v = cursor.getInt(0); cursor.close(); close(); return v; } catch (SQLiteException e) { e.getMessage(); return 0; } } /** * set db version no to * @param version * * @return status */ private boolean setVersionId(int version) { try { db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READWRITE); ContentValues values = new ContentValues(); values.put(AS_DB_VERSION_NUMBER, version); db.update(AS_DB_VERSION_NUMBER, values, AS_DB_VERSION_ID + " = 1", null); close(); return true; } catch (SQLiteException e) { e.getMessage(); return false; } } } 

Puede utilizar estos códigos en su concurso

  • OnCreate () no es llamado por getWritableDatabase ()
  • Cómo ver la base de datos de aplicación de Android que se ejecuta en mi teléfono
  • ¿Cómo extender la clase SQLiteDatabase?
  • Utilice Insertar o Reemplazar en ContentProvider
  • No se puede copiar la base de datos SQLite de los activos
  • ¿La reinstalación de la aplicación suprime SQLiteDatabase o SharedPreferences?
  • ¿Cómo obtengo el mejor rendimiento con SQLite en Android?
  • ¿Cuántas filas puedo insertar en una tabla en SQLite Android?
  • Cómo utilizar la conexión SQLite desde la carpeta de activos
  • ¿Hay alguna posibilidad de sincronizar los datos de la tabla sqlite entre dos móviles android usando wi-fi
  • ¿Cómo puedo ordenar mi base de datos SQLITE en orden descendente, para una aplicación de Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.