2016-07-14 11 views
0

Ich habe eine SQLite-Datenbank in assets/databases/minitest.db gespeichert und ich versuche, es aus dem Ordner Assets in das lokale Dateisystem zu kopieren und öffnen Sie es dann.Tabelle fehlt in der Datenbank in sqlite

Wenn ich es öffne bekomme ich eine Ausnahme für die Tabelle nicht gefunden.

Ich bin mir ziemlich sicher, dass es mit der Datenbank selbst nicht stimmt, denn wenn ich es mit einem SQLite-Viewer öffne, sieht es gut aus. Ich habe dieses Problem seit ungefähr 2 Stunden gegoogelt und ich habe eine Menge ähnlicher Fragen gesehen, aber keine ihrer Lösungen scheint zu funktionieren, also weiß ich wirklich nicht, was ich tun soll.

Code:

mydatabase = new DataBaseHelper(c).myDataBase; 
Cursor mCursor = mydatabase.rawQuery("SELECT third FROM Trigrams WHERE first='" + first.toLowerCase() + "' AND second ='" + second.toLowerCase() + "' ORDER BY freq DESC LIMIT 0,3", null); 

komplette DataBaseHelper:

class DataBaseHelper extends SQLiteOpenHelper { 
    private Context mycontext; 
    private static final String DB_NAME = "minitest.db";  
    private static final String DB_PATH = "/data/data/" +  BuildConfig.APPLICATION_ID + "/databases/"; 
    private static final int DB_VERSION = 3; 
    public SQLiteDatabase myDataBase; 

    public DataBaseHelper(Context context) throws IOException { 
     super(context, DB_NAME, null, DB_VERSION); 
     this.mycontext = context; 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
      System.out.println("Database exists"); 
      opendatabase(); 
     } else { 
      System.out.println("Database doesn't exist"); 
      createdatabase(); 
      opendatabase(); 
     } 
    } 

    public void createdatabase() throws IOException { 
     boolean dbexist = checkdatabase(); 
     if (dbexist) { 
      System.out.println(" Database exists."); 
     } else { 
      this.getReadableDatabase(); 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       throw new Error("Error copying database"); 
      } 
     } 
    } 

    private boolean checkdatabase() { 

     boolean checkdb = false; 
     try { 
      String myPath = DB_PATH + DB_NAME; 
      File dbfile = new File(myPath); 
      checkdb = dbfile.exists(); 
     } catch (SQLiteException e) { 
      System.out.println("Database doesn't exist"); 
     } 
     return checkdb; 
    } 

    private void copydatabase() throws IOException { 
     //Open your local db as the input stream 
     InputStream myinput = mycontext.getAssets().open("databases/" + DB_NAME); 

     // Path to the just created empty db 
     String outfilename = DB_PATH + DB_NAME; 

     //Open the empty db as the output stream 
     OutputStream myoutput = new FileOutputStream(outfilename); 

     // transfer byte to inputfile to outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myinput.read(buffer)) > 0) { 
      myoutput.write(buffer, 0, length); 
     } 

     //Close the streams 
     myoutput.flush(); 
     myoutput.close(); 
     myinput.close(); 
    } 

    public void opendatabase() throws SQLException { 
     //Open the database 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY); 
    } 

    public synchronized void close() { 
     if (myDataBase != null) { 
      myDataBase.close(); 
     } 
     super.close(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     if (newVersion > oldVersion) 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 
} 

Fehlerprotokoll:

E/SQLiteLog: (1) no such table: Trigrams 
E/InputEventReceiver: Exception dispatching input event. 
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback 
E/MessageQueue-JNI: android.database.sqlite.SQLiteException: no such table: Trigrams (code 1): , while compiling: SELECT third FROM Trigrams WHERE first='a' AND second ='baby' ORDER BY freq DESC LIMIT 0,3 
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889) 
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500) 
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58) 
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37) 
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1355) 
    at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1294) 
    at com.chair49.sentimentkeyboard.analysis.NextWord.getNextWords(NextWord.java:38) 
    at com.chair49.sentimentkeyboard.SimpleIME.onKey(SimpleIME.java:125) 
    at android.inputmethodservice.KeyboardView.detectAndSendKey(KeyboardView.java:828) 
    at android.inputmethodservice.KeyboardView.repeatKey(KeyboardView.java:1371) 
    at android.inputmethodservice.KeyboardView.onModifiedTouchEvent(KeyboardView.java:1281) 
    at android.inputmethodservice.KeyboardView.onTouchEvent(KeyboardView.java:1214) 
    at android.view.View.dispatchTouchEvent(View.java:9337) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554) 
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2198) 
    at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2432) 
    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1746) 
    at android.app.Dialog.dispatchTouchEvent(Dialog.java:787) 
    at android.inputmethodservice.SoftInputWindow.dispatchTouchEvent(SoftInputWindow.java:93) 
    at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2393) 
    at android.view.View.dispatchPointerEvent(View.java:9557) 
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4263) 
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4102) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3697) 
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3663) 
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3789) 
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3671) 
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3846) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3697) 
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3663) 
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3671) 
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3644) 
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5955) 
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5929) 
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5890) 
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6058) 
    at android.view.InputEventReceiver.dispatchInputEvent(Inp 
07-14 14:12:42.161 14083-14083/com.chair49.sentimentkeyboard E/AndroidRuntime: FATAL EXCEPTION: main 
+0

Was passiert, wenn Sie die '.db' Datei mit Androids' sqlite3' Befehlszeile zu öffnen versuchen? –

+0

Ich könnte mich irren .. Aber ich glaube, dass onUpgrade versagt. Sie rufen auf: opendatabase(), die Datenbank öffnet. Dies verursacht onUpgrade() und es wird versuchen, aus dem Asset-Ordner zu kopieren.Da Ihre Datenbank jedoch geöffnet ist, können Sie nicht schreiben, und auf diese Weise behält Ihre App die alte Datenbank bei. – W0rmH0le

+0

Gibt es eine Tabelle namens Trigrams? Ist die Schreibweise korrekt? –

Antwort

0

Ich glaube, dass die Datenbank nicht aktualisiert wird. Ich habe ähnliches Problem mit der Datenbank in asset Ordner konfrontiert.

-Workflow während onUpdate:

Wenn Sie Ihre Datenbank aktualisieren (es ist bereits vorhanden), würden folgende Methoden aufgerufen werden:

opendatabase()->SQLiteDatabase.openDatabase() 

Dies wird Ihre Datenbank öffnen und auch wird onUpgrade() auslösen.

In Ihrem onUpgrade(), Sie versuchen:

onUpgrade()->copydatabase() 

jedoch Datenbank geöffnet wird Sie nicht in der Lage sein wird, eine Datei IOException und Datenbank wird nicht aktualisiert minitest.db

überschrieben Dadurch wird.

Sie haben diese Ausnahme nicht gesehen, weil Sie mit IOException umgehen.

Wie Sie bestätigen

Sie deinstallieren/installieren (oder einfach nur Daten löschen) App. Wenn es funktioniert, scheint es, dass die Datenbank korrigiert wurde, aber während einer Aktualisierung ist es fehlgeschlagen, dass Ihre Tabellen nicht aktualisiert wurden.

Sie können auch die Datenbanknummer auf 4 aktualisieren und die Protokollmeldungen überprüfen und bestätigen, dass onUpgrade() fehlschlägt.

Umgehung

Dies ist, wie ich tun:

class DataBaseHelper extends SQLiteOpenHelper { 
    private boolean shouldBeUpdated; 

    public DataBaseHelper(Context context) throws IOException { 
     ... 
     shouldBeUpdated = false; 

     if (dbexist) { 
      System.out.println("Database exists"); 
      opendatabase(); 
     } else { 
      System.out.println("Database doesn't exist"); 
      createdatabase(); 
      opendatabase(); 
     } 
    } 

    public void opendatabase() throws SQLException { 
     String mypath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READONLY); 

     // CLOSE DATABASE BEFORE UPDATING IT 
     close(); 

     if(shouldBeUpdated) { 
      try { 
       copydatabase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     if (newVersion > oldVersion) 
      shouldBeUpdated = true; 
    } 
} 
+0

Das hat es behoben. Vielen Dank :) – user1762507

Verwandte Themen