Обновите предварительно заполненную базу данных без потери текущих данных - PullRequest
0 голосов
/ 12 декабря 2018

В настоящее время я работаю над приложением для Android, которое поставляется с предварительно заполненной базой данных.Предварительно заполненный БД находится в папке активов, и при первом запуске БД копируется в папку данных устройства.

Имя базы данных - «Events.db», и в этой предварительно заполненной базе данных есть 3 таблицы.Это СОБЫТИЯ, USER_EVENTS & УВЕДОМЛЕНИЯ.EVENTSTable содержит 240 записей, таблица NOTIFICATIONS содержит 1 запись, а таблица USER_EVENTS пуста.Эта USER_EVENTS пустая таблица заполняется, когда пользователь сохраняет некоторые данные.В будущем, когда я захочу добавить больше строк в таблицу EVENTS, не затрагивая другие данные таблицы, мне нужно найти способ.Просто обновить таблицу EVENTS, не затрагивая введенные пользователем данные в таблице USER_EVENTS.Поэтому я попытался изменить номер версии базы данных и, когда он меняется, активируется метод onUpgrade и попытаться добиться того, чего я хочу.Но я понятия не имею, как это сделать. Есть ли способ достичь такого сценария?Или какое-нибудь предложение с примером?

В настоящее время это методы в моем классе SqliteopenHelper.

public class DatabaseHelper extends SQLiteOpenHelper {

private static final String DB_PATH = "/data/data/com.calendar.shanu.calendar/databases/";

    private static final String DB_NAME = "Events.db";
    private static final int DB_VERSION = 1;
    private final Context myContext;
    public SQLiteDatabase db;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
            this.getWritableDatabase();
        } else {
            this.getWritableDatabase();
            try {
                this.close();
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }

    }

    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
            //checkDB.setVersion(DB_VERSION);
        } catch (SQLiteException e) {
        }
        if (checkDB != null)
            checkDB.close();
        return checkDB != null ? true : false;
    }

    private void copyDataBase() throws IOException {

        InputStream myInput = myContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[2048];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();

        //myDataBase.setVersion(DATABASE_VERSION);
    }

    public void opendb() throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
        Log.d("Test", "Database version: " +db.getVersion());
    }

    @Override
    public synchronized void close() {
        if (db != null)
            db.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if(newVersion > oldVersion){
            myContext.deleteDatabase(DB_NAME);
            try {
                copyDataBase();
                Log.d("CopyDB", "in onUpgrade. Old is: " + oldVersion + " New is: " + newVersion);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    }
public void closedb(){
        if (db!=null){
            db.close();
        }
    }

//Database Insert, Update, Delete methods are in the below
}

Любая помощь будет по достоинству оценена.

1 Ответ

0 голосов
/ 12 декабря 2018

Есть ли способ достичь такого сценария?

Да, возможно, не идеально, но в принципе: -

  1. Назовите новую базу данных как-то иначе и скопируйте впапка активов.
  2. Откройте его с помощью аналогичного помощника, который скопирует его из папки ресурсов, после чего
  3. продолжит и скопирует строки из соответствующей таблицы и вставит их в соответствующую таблицу предыдущей / старой базы данных.

Возможно, все инициировано с onUpgrade после увеличения номера версии.

Дополнительный комментарий: -

Не могли бы вы показать мне простой пример кода.Я думаю, что копирование данных с использованием курсора - это хороший подход, но я не понимал, как читать таблицы из двух таблиц.

Вот пример выполнения всего этого, включая копирование из ресурсов

Предполагается, что исходная база данных называется events.db и имеет 3 таблицы, а именно: event_table1 (заполнено), event_table2 (также заполнено) и event_table3 empty.

Новая база данных, заполненная event_table3 , называется events_extra.db и помещена в папку ресурсов.

Один класс (не может быть обеспокоен использованием подкласса SQliteOpenHelper) с именем ImportFromSecondaryDB копирует БД из папки активов в качестве второй базы данных, открывает обе, извлекает все строки из вторичной БД (однапросто скопировал из ресурсов) 3-ю таблицу и вставил строки в исходную БД.Наконец, он удаляет все строки из вторичной базы данных.

public class ImportFromSecondaryDB {
    public static final int IFSDB_COMPLETIONCODE_ALLREADYDONE = 1;
    public static final int IFSDB_COMPLETIONCODE_ERRORCOPYINGDBFROMASSET = 2;
    SQLiteDatabase mPrimaryDB;
    SQLiteDatabase mSecondaryDB;
    int mCompletionCode = 0;
    int stage = 0;

    ImportFromSecondaryDB(Context context, String primaryDBName, String secondaryDBName) {

        File primaryDBFile = new File(context.getDatabasePath(primaryDBName).getPath());
        File secondaryDBFile = new File(context.getDatabasePath(secondaryDBName).getPath());
        byte[] buffer = new byte[4096];

        if (!primaryDBFile.exists()) {
            throw new RuntimeException("Unable to Import as the Primary Database does not exist!");
        }
        if (secondaryDBFile.exists()) {
            mCompletionCode = IFSDB_COMPLETIONCODE_ALLREADYDONE;
            return;
        }

        InputStream is;
        OutputStream os;
        int length = 0;
        int copied = 0;

        try {
            is = context.getAssets().open(secondaryDBName);
            stage++;
            os = new FileOutputStream(secondaryDBFile);
            stage++;
            while ((length = is.read(buffer)) > 0) {
                copied = copied + length;
                os.write(buffer);
            }
            stage++;
            os.flush();
            stage++;
            os.close();
            stage++;
            is.close();
            stage++;
        } catch (IOException e) {
            e.printStackTrace();
            mCompletionCode = IFSDB_COMPLETIONCODE_ERRORCOPYINGDBFROMASSET;
            throw new RuntimeException(
                    "Error copying secondary database from Asset " + secondaryDBName +
                            " to " + secondaryDBFile.getPath() + " at stage " + String.valueOf(stage)
            );
        }
        mPrimaryDB = SQLiteDatabase.openDatabase(primaryDBFile.getPath(),null,SQLiteDatabase.OPEN_READWRITE);
        mSecondaryDB = SQLiteDatabase.openDatabase(secondaryDBFile.getPath(),null,SQLiteDatabase.OPEN_READWRITE);

        ContentValues cv = new ContentValues();
        Cursor csr = mSecondaryDB.query("event_table3",null,null,null,null,null,null);
        mPrimaryDB.beginTransaction();
        while (csr.moveToNext()) {
            cv.clear();
            cv.put("name",csr.getString(csr.getColumnIndex("name")));
            mPrimaryDB.insert("event_table3",null,cv);
        }
        mPrimaryDB.setTransactionSuccessful();
        mPrimaryDB.endTransaction();
        mSecondaryDB.delete("event_table3",null,null); //???????
        mPrimaryDB.close();
        mSecondaryDB.close();
    }

    public int getCompletionCode() {
        return this.mCompletionCode;
    }  
}
  • Примечание. Можно использовать getCompletionCode, чтобы определить, существует ли проблема (уже выполненная), которая не привела к возникновению исключения.
  • Обратите внимание, что это не было проверено так много, и он был составлен на скорую руку, поскольку он предназначен только для руководства.

Ниже приведен код, который использовался для вызовавыше из Activity: -

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dumpAllThreeTables(); // Dump Existing tables
        ImportFromSecondaryDB mIFSDB = new ImportFromSecondaryDB(this,"events.db","events_extra.db"); // Do the import
        dumpAllThreeTables(); // Dump the changed tables
    }

    private void dumpAllThreeTables() {

        SQLiteDatabase mainDB = SQLiteDatabase.openDatabase(this.getDatabasePath("events.db").getPath(),null,SQLiteDatabase.OPEN_READWRITE);
        Cursor csr = mainDB.query("event_table1",null,null,null,null,null,null);
        DatabaseUtils.dumpCursor(csr);
        csr = mainDB.query("event_table2",null,null,null,null,null,null);
        DatabaseUtils.dumpCursor(csr);
        csr = mainDB.query("event_table3",null,null,null,null,null,null);
        DatabaseUtils.dumpCursor(csr);
        csr.close();
        mainDB.close();
    }
}

Первый набор сброшенных таблиц (не end ничего в event_table3): -

12-12 10:43:38.766 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534c2808
12-12 10:43:38.770 2842-2842/? I/System.out: 0 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=1
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=A
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 1 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=2
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=B
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 2 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=3
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=C
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 3 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=4
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=D
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 4 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=5
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=E
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 5 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=6
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=F
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 6 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=7
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=G
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 7 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=8
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=H
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 8 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=9
12-12 10:43:38.770 2842-2842/? I/System.out:    mainname=I
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: <<<<<
12-12 10:43:38.770 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534af7a8
12-12 10:43:38.770 2842-2842/? I/System.out: 0 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=1
12-12 10:43:38.770 2842-2842/? I/System.out:    secondaryname=Horse
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 1 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=2
12-12 10:43:38.770 2842-2842/? I/System.out:    secondaryname=Cow
12-12 10:43:38.770 2842-2842/? I/System.out: }
12-12 10:43:38.770 2842-2842/? I/System.out: 2 {
12-12 10:43:38.770 2842-2842/? I/System.out:    id=3
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Rabbit
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 3 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=4
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Hare
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 4 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=5
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Cat
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 5 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=6
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Dog
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 6 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=7
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Porcupine
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 7 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=8
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Elephant
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 8 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=9
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Sheep
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: 9 {
12-12 10:43:38.774 2842-2842/? I/System.out:    id=10
12-12 10:43:38.774 2842-2842/? I/System.out:    secondaryname=Goat
12-12 10:43:38.774 2842-2842/? I/System.out: }
12-12 10:43:38.774 2842-2842/? I/System.out: <<<<<
12-12 10:43:38.774 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534c6e1c
12-12 10:43:38.774 2842-2842/? I/System.out: <<<<<

Второй набор сброшенных таблиц (посмотрите, как event_table3(последний дамп) теперь содержит данные): -

12-12 10:43:38.790 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534ae284
12-12 10:43:38.790 2842-2842/? I/System.out: 0 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=1
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=A
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 1 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=2
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=B
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 2 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=3
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=C
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 3 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=4
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=D
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 4 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=5
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=E
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 5 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=6
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=F
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 6 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=7
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=G
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 7 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=8
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=H
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: 8 {
12-12 10:43:38.790 2842-2842/? I/System.out:    id=9
12-12 10:43:38.790 2842-2842/? I/System.out:    mainname=I
12-12 10:43:38.790 2842-2842/? I/System.out: }
12-12 10:43:38.790 2842-2842/? I/System.out: <<<<<
12-12 10:43:38.790 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534c44b4
12-12 10:43:38.794 2842-2842/? I/System.out: 0 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=1
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Horse
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 1 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=2
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Cow
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 2 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=3
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Rabbit
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 3 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=4
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Hare
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 4 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=5
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Cat
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 5 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=6
12-12 10:43:38.794 2842-2842/? I/System.out:    secondaryname=Dog
12-12 10:43:38.794 2842-2842/? I/System.out: }
12-12 10:43:38.794 2842-2842/? I/System.out: 6 {
12-12 10:43:38.794 2842-2842/? I/System.out:    id=7
12-12 10:43:38.798 2842-2842/? I/System.out:    secondaryname=Porcupine
12-12 10:43:38.798 2842-2842/? I/System.out: }
12-12 10:43:38.798 2842-2842/? I/System.out: 7 {
12-12 10:43:38.798 2842-2842/? I/System.out:    id=8
12-12 10:43:38.802 2842-2842/? I/System.out:    secondaryname=Elephant
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 8 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=9
12-12 10:43:38.802 2842-2842/? I/System.out:    secondaryname=Sheep
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 9 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=10
12-12 10:43:38.802 2842-2842/? I/System.out:    secondaryname=Goat
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: <<<<<
12-12 10:43:38.802 2842-2842/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534c48c4
12-12 10:43:38.802 2842-2842/? I/System.out: 0 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=1
12-12 10:43:38.802 2842-2842/? I/System.out:    name=Z
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 1 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=2
12-12 10:43:38.802 2842-2842/? I/System.out:    name=X
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 2 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=3
12-12 10:43:38.802 2842-2842/? I/System.out:    name=Y
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 3 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=4
12-12 10:43:38.802 2842-2842/? I/System.out:    name=W
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 4 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=5
12-12 10:43:38.802 2842-2842/? I/System.out:    name=U
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 5 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=6
12-12 10:43:38.802 2842-2842/? I/System.out:    name=R
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 6 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=7
12-12 10:43:38.802 2842-2842/? I/System.out:    name=S
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: 7 {
12-12 10:43:38.802 2842-2842/? I/System.out:    id=8
12-12 10:43:38.802 2842-2842/? I/System.out:    name=T
12-12 10:43:38.802 2842-2842/? I/System.out: }
12-12 10:43:38.802 2842-2842/? I/System.out: <<<<<

Дополнительно 2 - Включение в onUpgrade

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String DB_PATH = "/data/data/com.calendar.shanu.calendar/databases/";

    private static final String DB_NAME = "events.db"; //<<<<<<<<<<< Changed for testing
    private static final int DB_VERSION = 2; //<<<<<<<<<< Changed for Testing
    private final Context myContext;
    public SQLiteDatabase db;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.myContext = context;
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
            this.getWritableDatabase();
        } else {
            this.getWritableDatabase();
            try {
                this.close();
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
            //checkDB.setVersion(DB_VERSION);
        } catch (SQLiteException e) {
        }
        if (checkDB != null)
            checkDB.close();
        return checkDB != null ? true : false;
    }

    private void copyDataBase() throws IOException {

        InputStream myInput = myContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[2048];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();

        //myDataBase.setVersion(DATABASE_VERSION);
    }

    public void opendb() throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READWRITE);
        Log.d("Test", "Database version: " +db.getVersion());
    }

    @Override
    public synchronized void close() {
        if (db != null)
            db.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if(newVersion > oldVersion){
            importFromSecondaryDB(myContext,db,"events_extra.db"); //<<<<<<<<<<
        }
    }
    public void closedb(){
        if (db!=null){
            db.close();
        }
    }

    private int importFromSecondaryDB(Context context, SQLiteDatabase maindb, String secondaryDBName) {


        File primaryDBFile = new File(maindb.getPath());
        File secondaryDBFile = new File(context.getDatabasePath(secondaryDBName).getPath());
        byte[] buffer = new byte[4096];

        // Check that the main database exist, if not then throw a runtime exception
        if (!primaryDBFile.exists()) {
            throw new RuntimeException("Unable to Import as the Primary Database does not exist!");
        }
        // If the secondary database exists then it has already been copied and thus data has been loaded
        // so return (can check returned code for allready done)
        if (secondaryDBFile.exists()) {
            return 1;
        }

        //Prepare for file handling (copy)
        InputStream is;
        OutputStream os;
        int length;
        int copied = 0;

        try {
            is = context.getAssets().open(secondaryDBName); // Get the assets file
            os = new FileOutputStream(secondaryDBFile); // Get the file to be written to
            // Loop though the asset file in chunks reading it and then writing to output
            while ((length = is.read(buffer)) > 0) {
                copied = copied + length;
                os.write(buffer);
            }
            // Copy done so flush and close files
            os.flush();
            os.close();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(
                    "Error copying secondary database from Asset " + secondaryDBName +
                            " to " + secondaryDBFile.getPath()
            );
        }
        // Open the newly copied database
        SQLiteDatabase mSecondaryDB = SQLiteDatabase.openDatabase(secondaryDBFile.getPath(),null,SQLiteDatabase.OPEN_READWRITE);

        //Copy the rows from the secondary (new) database, from table event_table3 to the main database's  event_table3
        //<<<<<<<<<< Note will have to be tailored to suit. >>>>>>>>>>>
        ContentValues cv = new ContentValues();
        // Extract the tables 
        Cursor csr = mSecondaryDB.query("event_table3",null,null,null,null,null,null);
        // Do in a Transaction
        maindb.beginTransaction();
        // Loop through extracted rows
        while (csr.moveToNext()) {
            cv.clear();
            cv.put("name",csr.getString(csr.getColumnIndex("name")));
            maindb.insert("event_table3",null,cv);
        }
        // ALl done so commit and close the transaction
        maindb.setTransactionSuccessful();
        maindb.endTransaction();
        // OPTIONAL delete the rows from the secondary table as they have been applied
        mSecondaryDB.delete("event_table3",null,null); //???????
        // Finally close the secondary database as done with it (main stays open)
        mSecondaryDB.close();
        return 0;
    }
}
...