SQL没有这样的表,但是存在
我使用sqlite3在python中制作了一个数据库文件。数据库保留2个表答案,问题
。我想在我的android应用中使用该文件,然后遵循 this 发布以复制它而不是创建它。我复制了该文件,如图所示实现了这些方法,但是我得到了一个sqliteException:no这样表:问题(代码1 sqlite_error):,在编译时:从问题中选择 * *。我在sqlite中进行了加倍,并在sqlite中进行了三次研究,表格在那里,名称是正确的。到处有什么问题?我的助手类看起来像这样:
public class DatabaseHelper extends SQLiteOpenHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
private static String DB_NAME ="quiz.db"; // Database name
private static int DB_VERSION = 1; // Database version
private final File DB_FILE;
private SQLiteDatabase mDataBase;
private final Context mContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
DB_FILE = context.getDatabasePath(DB_NAME);
this.mContext = context;
}
public void createDataBase() throws IOException {
// If the database does not exist, copy it from the assets.
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getReadableDatabase();
this.close();
try {
// Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
} catch (IOException mIOException) {
throw new Error("ErrorCopyingDataBase");
}
}
}
// Check that the database file exists in databases folder
private boolean checkDataBase() {
return DB_FILE.exists();
}
// Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = mContext.getAssets().open(DB_NAME);
OutputStream mOutput = new FileOutputStream(DB_FILE);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
// Open the database, so we can query it
public boolean openDataBase() throws SQLException {
mDataBase = SQLiteDatabase.openDatabase(String.valueOf(DB_FILE), null, SQLiteDatabase.CREATE_IF_NECESSARY);
return mDataBase != null;
}
@Override
public synchronized void close() {
if(mDataBase != null) {
mDataBase.close();
}
super.close();
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
public void testQuery() {
mDataBase.rawQuery("select * from QUESTIONS;",null);
}
}
我这样称呼它:
helper = new DatabaseHelper(this);
try {
helper.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
try{
helper.openDataBase();
}catch (SQLException e){
e.printStackTrace();
}
helper.testQuery();
edit:
app/src/src/src/assets/quiz.db
.db
文件我物理上的路径复制到项目data/data/com.rocket.src/databases
此路径包含quiz.db
quiz.db-journal
和quiz.dbquiz.db
I made a database file in python using sqlite3. The database holds 2 tables ANSWERS,QUESTIONS
. I want to use that file in my android app and i followed this post to copy it instead of creating it. I copied the file,implemented the methods as shown,but I get an SQLiteException: no such table: QUESTIONS (code 1 SQLITE_ERROR): , while compiling: select * from QUESTIONS;
. I double and triplechecked my database in sqlite,the tables are there,the names are correct. What could be the issue at place? My helper class looks like this:
public class DatabaseHelper extends SQLiteOpenHelper {
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
private static String DB_NAME ="quiz.db"; // Database name
private static int DB_VERSION = 1; // Database version
private final File DB_FILE;
private SQLiteDatabase mDataBase;
private final Context mContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
DB_FILE = context.getDatabasePath(DB_NAME);
this.mContext = context;
}
public void createDataBase() throws IOException {
// If the database does not exist, copy it from the assets.
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getReadableDatabase();
this.close();
try {
// Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
} catch (IOException mIOException) {
throw new Error("ErrorCopyingDataBase");
}
}
}
// Check that the database file exists in databases folder
private boolean checkDataBase() {
return DB_FILE.exists();
}
// Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = mContext.getAssets().open(DB_NAME);
OutputStream mOutput = new FileOutputStream(DB_FILE);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
// Open the database, so we can query it
public boolean openDataBase() throws SQLException {
mDataBase = SQLiteDatabase.openDatabase(String.valueOf(DB_FILE), null, SQLiteDatabase.CREATE_IF_NECESSARY);
return mDataBase != null;
}
@Override
public synchronized void close() {
if(mDataBase != null) {
mDataBase.close();
}
super.close();
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
public void testQuery() {
mDataBase.rawQuery("select * from QUESTIONS;",null);
}
}
And I call it like this:
helper = new DatabaseHelper(this);
try {
helper.createDataBase();
} catch (IOException e) {
e.printStackTrace();
}
try{
helper.openDataBase();
}catch (SQLException e){
e.printStackTrace();
}
helper.testQuery();
EDIT:
app/src/main/assets/quiz.db
The path from the.db
file I physically copied to the projectdata/data/com.rocket.src/databases
This path containsquiz.db
quiz.db-journal
andquiz.dbquiz.db
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您发布的链接是一个旧的链接并且有缺陷,它不能满足以后版本的Android。以后的版本默认用于使用 wal ( w rite- rite- a head l ogging),其中更改写入文件(数据库文件以-WAL为后缀)。
如果数据库文件是通过sqlitedatabase opendatabasemethod创建的,则使用create_if_neusctary创建数据库文件,然后覆盖WAL文件是为创建数据库而不是oftritten oftritten数据库(使用
this.getReadAbledabledatabase()使用
this.getReadAbledatabase()您的情况)
。 SQLITE检测到这一点,并将数据库视为损坏。 OpenDatabase捕获了这一点,并提供一个数据库,可以创建一个新的数据库,因此您最终获得了仅具有SQLITE_MASTER表的数据库。
以上所有内容在历史上都用于规避数据库文件夹/目录(数据/数据/数据库),如果正确的方法应该是在数据库文件不存在的情况下创建文件夹(使用GetWritabledabledatabase或可读性将创建数据库目录)。
对于任何版本的Android,正确,更有效的方法是检查数据库文件是否存在。如果确实这样做,则不会复制资产并返回通常的过程。
否则(如果数据库文件不存在),请获取父(数据库文件夹),请检查是否存在并且如果不存在,则将创建目录。然后可以从资产复制数据库文件。
这是执行以上db_name是数据库文件的名称的上述片段: -
此文件仅能进行更有效 - 开放。相反,它只会检查文件系统。
The link you posted is an old link and has a flaw, it does not cater for later versions of Android. Later versions default to using WAL (Write-Ahead Logging) where changes are written to a file (database file suffixed with -wal).
If the database file is created via the SQLiteDatabase openDatabaseMethod with CREATE_IF_NECESSARY and then overwritten the WAL file is for the created database NOT the overwritten database (the use of
this.getReadableDatabase();
does this in your case). SQLite detects this and considers the database as corrupt. The openDatabase catches this and, to provide a database, creates a new database and hence you end up with a database that only has the sqlite_master table.All of the above was historically used to circumvent the databases folder/directory (data/data/databases) not existing, when the correct method should have been to create the folder if the database file doesn't exist (using getWritabledatabase or Readable will create the databases directory).
The correct and more efficient way, for any version of Android is to check if the database file exists. If it does then don't copy the asset and return to the usual process.
Otherwise (if the database file does not exist), then get the parent (the databases folder), check if that exists and if not then make the directory. The database file can then be copied from the asset.
Here's a snippet that does the above where DB_NAME is the name of the database file :-
This file only approach is more efficient as it does not incur the increased processing required to open and initialise a database, just for it to then be overwritten and re-opened. Instead it just checks the file system.