简体   繁体   English

在 SQLiteOpenHelper 中未调用 onUpgrade

[英]onUpgrade is not getting called in SQLiteOpenHelper

The method onUpgrade is not getting called even if it gets the DB version greater than the current.即使获得的数据库版本高于当前版本,也不会调用onUpgrade方法。

I verified the DB version using the following command and it is 6 currently.我使用以下命令验证了数据库版本,目前是6

sqlite> PRAGMA user_version;
6

In the constructor, I'm passing the following ( version 7 ),在构造函数中,我传递了以下内容(版本 7 ),

super(context, DB_NAME, null, 7);

Note: My class DBHelper extends SQLiteOpenHelper and the above line is present in the constructor of DBHelper.注意:我的 class DBHelper 扩展了 SQLiteOpenHelper,上面的行出现在 DBHelper 的构造函数中。

SQLite version: 3.32.3 SQLite 版本:3.32.3

As I'm passing the new (greater) DB version, I expect the onUpgrade to be called.当我传递新的(更大的)数据库版本时,我希望调用 onUpgrade。 But the onUpgrade is never called.但是永远不会调用 onUpgrade。 Am I missing any other thing?我还缺少其他东西吗?

UPDATE 1:更新 1:

DBHelper.class DBHelper.class

class DBHelper extends SQLiteOpenHelper
{
    @Inject
    public DBHelper(final Context context)
    {
        this(context, DBContracts.DATABASE_FILE_NAME);
    }

    DBHelper(final Context context, final String databaseFileName)
    {
        super(context, databaseFileName, null, DBContracts.DATABASE_VERSION);
        Logger.i("APPTAG", "DBHelper constructor");
        Logger.i("APPTAG", "DATABASE_VERSION : " + DBContracts.DATABASE_VERSION);
    }

    @Override
    public void onCreate(final SQLiteDatabase db)
    {
        Logger.i("APPTAG", "onCreate");
        // create scripts
    }

    @Override
    public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion)
    {
        Logger.i("APPTAG", "onUpgrade");
        Logger.i("APPTAG", "oldVersion: " + oldVersion);
        Logger.i("APPTAG", "newVersion: " + newVersion);
        // upgrade scripts
    }

    @Override
    public void onConfigure(final SQLiteDatabase db)
    {
        Logger.i("APPTAG", "onConfigure");
        Logger.i("APPTAG", "DB version: " + db.getVersion());

        try {
            Logger.i("APPTAG", "DB path: " + db.getPath());
            int version = ((Long) DatabaseUtils.longForQuery(db, "PRAGMA user_version;", null)).intValue();
            Logger.i("APPTAG", "onConfigure version: " + version);
        } catch (Exception e) {
            Logger.e("APPTAG", "Error" + e, e);
        }

        super.onConfigure(db);
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Logger.i("APPTAG", "onDowngrade");
        Logger.i("APPTAG", "oldVersion: " + oldVersion);
        Logger.i("APPTAG", "newVersion: " + newVersion);
        super.onDowngrade(db, oldVersion, newVersion);
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        Logger.i("APPTAG", "onOpen");
        Logger.i("APPTAG", "DB version: " + db.getVersion());
        super.onOpen(db);
    }
}

And this is the log I see,这是我看到的日志,

05-04 07:47:33.021  4295  4295 I APPTAG: DBHelper constructor
05-04 07:47:33.021  4295  4295 I APPTAG: DATABASE_VERSION : 7
05-04 07:47:33.023  4295  4295 I APPTAG: UpdatesDB constructor
05-04 07:47:33.023  4295  4295 I APPTAG: SQLiteDatabaseWrapperFactory create
05-04 07:47:33.029  4295  4295 I APPTAG: onConfigure
05-04 07:47:33.030  4295  4295 I APPTAG: DB version: 7
05-04 07:47:33.030  4295  4295 I APPTAG: DB path: /data/user/0/<application-name>/databases/updates.db
05-04 07:47:33.030  4295  4295 I APPTAG: onConfigure version: 7
05-04 07:47:33.031  4295  4295 I APPTAG: onOpen
05-04 07:47:33.031  4295  4295 I APPTAG: DB version: 7

Interestingly, if I execute this command PRAGMA user_version;有趣的是,如果我执行这个命令PRAGMA user_version; directly on the database, I get the version as 6. But when I tried through the code (as in onConfigure), it gives me 7. Due to this, it skips the onUpgrade method as per this code .直接在数据库上,我得到的版本为 6。但是当我尝试通过代码(如在 onConfigure 中)时,它给了我 7。因此,它根据此代码跳过了 onUpgrade 方法。

Could anyone help me understand why the db version is getting reported as 7 when I fetch it through code?谁能帮我理解为什么当我通过代码获取数据库版本时,它被报告为 7?

Clarifications:说明:

  • I'm calling getWritableDatabase() to get the db instance.我正在调用getWritableDatabase()来获取数据库实例。
  • DBContracts.DATABASE_VERSION is set to 7 DBContracts.DATABASE_VERSION设置为 7

I believe that your issue lies outside of the code in your question, or perhaps it is a misuse the fist constructor (perhaps comment that out and see how you fare).我相信您的问题不在您问题的代码范围内,或者可能是滥用了第一个构造函数(也许将其注释掉并查看您的表现)。

Consider this modification (primarily see the end of the code and the ie the added getDatabaseVersion method), to include retrieval of the version number prior to to opening the database and other minor changes for my convenience:-考虑这种修改(主要查看代码的末尾和即添加的getDatabaseVersion方法),包括在打开数据库之前检索版本号以及为方便起见的其他小改动:-

class DBHelper extends SQLiteOpenHelper {
    //@Inject
    /* MAKE SURE THIS CONSTRUCTOR CAN'T BE USED, it could cause issues
    public DBHelper(final Context context) {
        this(context, DBContracts.DATABASE_FILE_NAME);
    }
     */
    
    /* Changed logger to Log.i throughout */
    
    DBHelper(final Context context, final String databaseFileName) {
        super(context, databaseFileName, null, DBContracts.DATABASE_VERSION);
        Log.i("APPTAG","PREOPEN VERSION = " + getDatabaseVersion(context)); //<<<<<<<<<< ADDED 
        Log.i("APPTAG", "DBHelper constructor");
        Log.i("APPTAG", "DATABASE_VERSION : " + DBContracts.DATABASE_VERSION);
    }

    @Override
    public void onCreate(final SQLiteDatabase db) {
        Log.i("APPTAG", "onCreate");
        // create scripts
    }

    @Override
    public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
        Log.i("APPTAG", "onUpgrade");
        Log.i("APPTAG", "oldVersion: " + oldVersion);
        Log.i("APPTAG", "newVersion: " + newVersion);
        // upgrade scripts
    }

    @Override
    public void onConfigure(final SQLiteDatabase db) {
        Log.i("APPTAG", "onConfigure");
        Log.i("APPTAG", "DB version: " + db.getVersion());

        try {
            Log.i("APPTAG", "DB path: " + db.getPath());
            int version = ((Long) DatabaseUtils.longForQuery(db, "PRAGMA user_version;", null)).intValue();
            Log.i("APPTAG", "onConfigure version: " + version);
        } catch (Exception e) {
            Log.e("APPTAG", "Error" + e, e);
        }

        super.onConfigure(db);
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.i("APPTAG", "onDowngrade");
        Log.i("APPTAG", "oldVersion: " + oldVersion);
        Log.i("APPTAG", "newVersion: " + newVersion);
        super.onDowngrade(db, oldVersion, newVersion);
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        Log.i("APPTAG", "onOpen");
        Log.i("APPTAG", "DB version: " + db.getVersion());
        super.onOpen(db);
    }

    /*<<<<<<<<<< ADDED >>>>>>>>>>*/
    private int getDatabaseVersion(Context context) {
        int rv = -666;
        SQLiteDatabase db = null;
        File databaseFilePath = new File(context.getDatabasePath(DBContracts.DATABASE_FILE_NAME).getPath());
        File databaseDirectory = databaseFilePath.getParentFile();
        /* If database file does not exist AND version is 6 then create the databases directory and then create the database */
        if (! databaseFilePath.exists() && (DBContracts.DATABASE_VERSION == 6)) {
            databaseDirectory.mkdirs();
            db = SQLiteDatabase.openOrCreateDatabase(databaseFilePath.getPath(),null);
        }
        else {
            db = SQLiteDatabase.openDatabase(context.getDatabasePath(DBContracts.DATABASE_FILE_NAME).getPath(), null, SQLiteDatabase.OPEN_READWRITE);
        }
        if (db != null) {
            rv = db.getVersion();
            db.close();
        }
        return rv;
    }
}

Then the following code in an activity:-然后是活动中的以下代码:-

public class MainActivity extends AppCompatActivity {

    DBHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new DBHelper(this,DBContracts.DATABASE_FILE_NAME);
        SQLiteDatabase db = dbHelper.getWritableDatabase(); //<<<<<<<<<< Force an open of the db
    }
}

The App was run twice:-该应用程序运行了两次:-

  1. First with DBContracts.DATABASE_VERSION as 6首先将 DBContracts.DATABASE_VERSION 设置为 6
    1. This would then create version 0, which would then be changed by the SQLiteOpenHelper to be version 6这将创建版本 0,然后由 SQLiteOpenHelper 将其更改为版本 6
  2. Second without uninstalling the App with DBContracts.DATABASE_VERSION as 7第二个没有卸载 DBContracts.DATABASE_VERSION 为 7 的应用程序

The results being:-结果是:-

2022-05-05 21:30:06.639 I/APPTAG: PREOPEN VERSION = 0
2022-05-05 21:30:06.640 I/APPTAG: DBHelper constructor
2022-05-05 21:30:06.640 I/APPTAG: DATABASE_VERSION : 6
2022-05-05 21:30:06.643 I/APPTAG: onConfigure
2022-05-05 21:30:06.644 I/APPTAG: DB version: 0
2022-05-05 21:30:06.644 I/APPTAG: DB path: /data/user/0/a.a.so721000750unupdatenotbeingcalled/databases/testdb
2022-05-05 21:30:06.645 I/APPTAG: onConfigure version: 0
2022-05-05 21:30:06.645 I/APPTAG: onCreate
2022-05-05 21:30:06.655 I/APPTAG: onOpen
2022-05-05 21:30:06.655 I/APPTAG: DB version: 6 
  • as expected (onUpgrade not called as there is no upgrade rather onCreate is called which sets the version as 6).正如预期的那样(没有调用 onUpgrade,因为没有升级,而是调用 onCreate,它将版本设置为 6)。

Then:-然后:-

2022-05-05 21:33:37.138 I/APPTAG: PREOPEN VERSION = 6
2022-05-05 21:33:37.138 I/APPTAG: DBHelper constructor
2022-05-05 21:33:37.138 I/APPTAG: DATABASE_VERSION : 7
2022-05-05 21:33:37.140 I/APPTAG: onConfigure
2022-05-05 21:33:37.141 I/APPTAG: DB version: 6
2022-05-05 21:33:37.141 I/APPTAG: DB path: /data/user/0/a.a.so721000750unupdatenotbeingcalled/databases/testdb
2022-05-05 21:33:37.141 I/APPTAG: onConfigure version: 6
2022-05-05 21:33:37.141 I/APPTAG: onUpgrade
2022-05-05 21:33:37.142 I/APPTAG: oldVersion: 6
2022-05-05 21:33:37.142 I/APPTAG: newVersion: 7
2022-05-05 21:33:37.152 I/APPTAG: onOpen
2022-05-05 21:33:37.153 I/APPTAG: DB version: 7
  • this exactly as expected;这完全符合预期; that is那是
    • the database before an attempt to open is version 6 and尝试打开之前的数据库是版本 6 并且
    • the DATABASE_VEARSION is 7. DATABASE_VEARSION 是 7。
    • At onConfigure the version is 6.在 onConfigure 版本是 6。
    • onUpgrade is called to change from 6 to 7 and onUpgrade被调用以从 6 更改为 7 并且
    • finally the version is 7 when the database is opened.最后打开数据库时版本为 7。

A third run, without changing anything (so db already at version 7) then:-第三次运行,不做任何更改(所以 db 已经是版本 7)然后:-

2022-05-05 21:43:02.167 I/APPTAG: PREOPEN VERSION = 7
2022-05-05 21:43:02.167 I/APPTAG: DBHelper constructor
2022-05-05 21:43:02.167 I/APPTAG: DATABASE_VERSION : 7
2022-05-05 21:43:02.170 I/APPTAG: onConfigure
2022-05-05 21:43:02.170 I/APPTAG: DB version: 7
2022-05-05 21:43:02.170 I/APPTAG: DB path: /data/user/0/a.a.so721000750unupdatenotbeingcalled/databases/testdb
2022-05-05 21:43:02.171 I/APPTAG: onConfigure version: 7
2022-05-05 21:43:02.171 I/APPTAG: onOpen
2022-05-05 21:43:02.171 I/APPTAG: DB version: 7
  • Which bar the questioned (as per the comments) 2 logged lines and the additional PREOPEN logged line basically matches what you have shown .哪个栏被质疑(根据评论)2 条记录行和附加的 PREOPEN 记录行基本上与您显示的内容相匹配。 Which could be your issue if for some reason you are incorrect when you say "Interestingly, if I execute this command PRAGMA user_version; directly on the database, I get the version as 6."如果出于某种原因,当您说“有趣的是,如果我执行此命令 PRAGMA user_version;直接在数据库上,我得到的版本为 6”时,这可能是您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM