- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我创建了一个由表组成的 sqlite 数据库,数据库中填充了大约 2000 行。
我能够查询此表,并且当我通过模拟器执行此操作时一切正常。
但是当我在移动设备上测试它时,它会抛出以下错误:
android.database.sqlite.SQLiteException: no such table: person (code 1): , while compiling: SELECT name from person WHERE rowid = 292
当我在设备上尝试时,我希望我填充的 sqlite 数据库在我的设备上自动可用,但根据上述错误,情况似乎并非如此。
I did have a look through past issues and they do not match my issue.
I did not set my own path for the db storage location.
When I looked under Device File Explorer, the path for the database is /data/data/com.somepackage.myappname/databases/person
我已经尝试卸载该应用程序并再次重新安装,但没有任何区别。
我的 sdk 设置详细信息(如果相关)。
minSdkVersion 16
targetSdkVersion 27
Mobile device: Using Android version 8.0.0
请告知如何让数据库在安装时自动随应用程序一起提供(当我在 Android Studio 上单击运行时)。
这就是我将数据加载到数据库中的方式。这只运行了一次,我目前已经将这段代码注释掉了。
try {
SQLiteDatabase database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
database.execSQL("DROP TABLE IF EXISTS person");
database.execSQL("CREATE TABLE IF NOT EXISTS person (name VARCHAR, name_size INT(8))");
BufferedReader br = new BufferedReader(new InputStreamReader(getAssets().open("person.txt")));
String line;
while ((line = br.readLine()) != null) {
String sql = "INSERT INTO person (name, name_size) VALUES ('" + line + "', " + line.length() + ")";
database.execSQL(sql);
}database.close();
}
catch (Exception e){
e.printStackTrace();
}
我在 onCreate 方法下初始化数据库。
database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
单击按钮时,将执行以下方法。错误发生在该方法的第一行。
private String retrieveNextPerson(int randomIndex){
//error on this raw query
Cursor cursor = database.rawQuery("SELECT name from person WHERE rowid = " + randomIndex, null);
int wordIndex = cursor.getColumnIndex("name");
cursor.moveToFirst();
return cursor.getString(wordIndex);
}
最佳答案
假设您没有错误地认为在模拟器(或任何设备)上运行应用程序会更改包,以便分发将包含填充的数据库
分发预填充的数据库涉及
c) 从 Assets 文件夹中检索它。
SQLiteAssethelper
数据库文件需要存在于数据库文件夹中(您很可能需要创建它))。 然后我怀疑你过早地调用了:-
database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
这样做会创建没有人员表的人员数据库,从而导致您所描述的失败。
您需要在使用上述行之前加载数据。
或者,如果您在 database = this.openOrCreateDatabase("person", MODE_PRIVATE, null);
之后立即添加以下代码
Cursor csr = database.query("sqlite_master",null,"name='person'",null,null,null,null);
if (csr.getCount() < 1) {
database.execSQL("CREATE TABLE IF NOT EXISTS person (name VARCHAR, name_size INT(8))");
........ rest of the code that inserts data from the person.txt asset
}
表格将被创建。但是,它将是空的(您可以在此处复制 person.txt Assets 中的数据)
Thanks for reply. Not sure if you missed the part where I mentioned the database creation is already done and that part has been commented out. I invoked the db creation once and loaded it with data and the db is just sitting in the app now (at least for the emulator). The initialisation you mentioned should open an existing db with an existing table thus I don't see why that would be premature.
以下是对您的代码进行的非常可靠的修改,它将解决我认为最有可能出现的潜在问题:-
public class MainActivity extends AppCompatActivity {
public static final String DBNAME = "person";
public static final String TBNAME = "person";
public static final String COL_NAME = "name";
public static final String COL_NAME_SIZE = "name_size";
public static final String ASSET_FILENAME = "person.txt";
public static final String SQLITE_MASTER_TABLE = "sqlite_master";
public static final String COL_SQLITE_MATSER_NAME = "name";
static final int MIMINUM_ROWS_IN_PERSONTABLE = 1;
SQLiteDatabase db;
BufferedReader br;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPersonTable(); // Notes sets db either way
// FOR TESTING
long rows_in_person_table = DatabaseUtils.queryNumEntries(db,TBNAME);
Log.d(
"PERSON ROW COUNT",
"The number of rows in the " +
TBNAME +
" table is " +
String.valueOf(rows_in_person_table)
);
}
private void checkPersonTable() {
db = this.openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE,null);
// Database will now exist but it may or may not contain the person table so check sqlite_master
Cursor csr = db.query(
SQLITE_MASTER_TABLE,
new String[]{COL_SQLITE_MATSER_NAME},
COL_SQLITE_MATSER_NAME + "=?",
new String[]{TBNAME},
null,null,null
);
// Cursor will contain 1 row if the person table exists so check count
int person_table_count = csr.getCount();
csr.close();
// Before attemtping to create the Person table ensure that the assets file exists
// If not then throw a RunTime exception
if (person_table_count < 1) {
try {
if (!Arrays.asList(getResources().getAssets().list("")).contains(ASSET_FILENAME)) {
StringBuilder sb = new StringBuilder();
throw new RuntimeException("Asset file " +
ASSET_FILENAME +
" not found in the assets folder." +
" The following assets were found" +
sb
);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (person_table_count < 1) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TBNAME +
"(" +
COL_NAME + " TEXT," +
COL_NAME_SIZE + " INTEGER" +
")"
);
loadPersonsFromAssets();
} else {
// <<<<<<<<<< NOTE Optional will load data from assets if miminum nuber of rows
// aren't in the person table
if (DatabaseUtils.queryNumEntries(db,TBNAME) < MIMINUM_ROWS_IN_PERSONTABLE) {
loadPersonsFromAssets();
}
}
}
// Load the person table from the Assets File
private void loadPersonsFromAssets() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(getAssets().open(ASSET_FILENAME)));
String line, sql;
int lines_read = 0;
db.beginTransaction();
while ((line = br.readLine()) != null) {
sql = "INSERT INTO " + TBNAME + " VALUES('" + line + "'," + String.valueOf(line.length()) + ")";
db.execSQL(sql);
lines_read++;
}
db.setTransactionSuccessful();
db.endTransaction();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Asset File " + ASSET_FILENAME + " not found in the assets folder.");
}
}
}
这将:-
如果 Assets 文件 person.txt 不存在,那么您将得到类似于以下的异常:-
06-10 03:58:43.503 3097-3097/personthing.so50777840 E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{personthing.so50777840/personthing.so50777840.MainActivity}: java.lang.RuntimeException: Asset file person.txt not found in the assets folder. The following assets were found
found asset file :- images
found asset file :- notperson.txt
found asset file :- sounds
found asset file :- webkit
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Asset file person.txt not found in the assets folder. The following assets were found
found asset file :- images
found asset file :- notperson.txt
found asset file :- sounds
found asset file :- webkit
at personthing.so50777840.MainActivity.checkPersonTable(MainActivity.java:83)
at personthing.so50777840.MainActivity.onCreate(MainActivity.java:39)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
... 11 more
请注意,在此阶段数据库将存在(由于 openOrCreateDatabase
)并且它将包含两个表(sqlite_master 和 android_metadata)但不包含 person 表,例如:-
但是,创建正确的 Assets 文件 person.txt(将 notperson.txt 重命名为 person.text)将导致创建表并加载数据:-
例如如果 person.txt 是:-
然后运行该应用程序将导致日志包含:-
06-10 04:39:04.277 3325-3325/? D/PERSON ROW COUNT: The number of rows in the person table is 11
关于java - 在移动设备上找不到 sqlite db,但可以在模拟器上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50777840/
我当前正在存储给定产品的上传图像,如下所示: class Product(db.Model): images= db.ListProperty(db.Blob) # More prop
每次对架构或新迁移文件进行更改时,我都会运行以下命令: rake db:drop db:create db:migrate db:seed 是否有预先构建的等效方法来执行此操作? 我从我读到的内容中想
在 android 中使用房间作为数据库。当我试图在 sqlviewer 中查看数据时,在数据库文件中找不到表Myapp.db 文件为空。数据/data/packageName/databases/M
我搜索并尝试了很多次,但没有找到我的答案。我有一些用小 cucumber (在 Rails 项目中)编写的项目的功能文件。所有步骤都已定义,如果我单独启动它们,功能本身运行得很好。我可以将所有场景与我
您必须承认,对于 Rails 和数据库的新手来说,rubyonrails.org 上的官方解释使所有这四个任务听起来完全一样。引用: rake db:test:clone Recreate the
当我尝试运行时: heroku run rake db:drop db:create db:migrate 我得到错误: Running rake db:drop attached to termin
rake db:migrate 和 rake db:reset 之间的区别对我来说非常清楚。我不明白的是 rake db:schema:load 与前两者有何不同。 只是为了确保我在同一页面上: ra
我们都知道,我们可以使用 Azure 函数(使用 out 参数或使用 return)在 cosmos DB 中一次保存一个文档,例如: object outputDocument = new { i
我有一个包含 60 多个表的 mysql 数据库。这是在我将 joomla 版本 2.5.3 从本地灯移植到网络服务器时构建的。 我运行 mysql-db: 移植后我发现我无法登录 amdin 区域。
我想轻松地将现有数据库迁移到 Azure 托管。在我的项目中,我使用 Entity Framework DB First。有什么经验教训或例子可以说明如何做到这一点吗? 最佳答案 您本地使用什么数据库
所以,我一直在使用 MagicalRecord 开发 iPad 应用程序,最近在转移到自动迁移商店后我遇到了一些问题。我需要将我的 .db 文件从一个设备同步到另一个设备,所以我需要所有数据都在 .d
自从我在 Heroku 上部署并希望与生产相匹配后,我最近切换到 postgres 来开发一个 Rails 应用程序。当我将数据库名称设置为“postgres”时,我的应用程序安装了 Postgres
我使用 oledb 提供程序(SQLOLEDB 和 SQL Native OLEDB 提供程序)创建了一个示例应用程序。 案例 1:提供者 = SQLOLEDB hr = ::CoInitialize
我正在为 NodeJs 使用 mongodb 驱动程序,其中有 3 个方法: 1) db.collection.insert 2) 数据库.collection.insertOne 3) db.col
我是 datomic 的新手,我仍在努力弄清楚系统是如何构建的。特别是,我不明白 :db.part/db 扮演什么角色,因为每次安装架构时似乎都需要它。有人可以解释一下这一切意味着什么吗? (需要 '
Berkeley DB 是否有空间索引,例如 R-tree? 最佳答案 有人问the same question on the Oracle forum .还没有甲骨文回答。但答案是否定的,它没有任何
请解释一下这是什么意思 $db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE); 它给了我一个错误 "E
berkeley-db-je 的最新版本是什么? 来自 oracle , 为 7.5。 但来自maven存储库,它是 18.3.12。 有没有人知道更多的细节? 最佳答案 Berkeley DB Ja
我不明白查询构建器的替换和更新之间的区别。尤其是替换文档... This method executes a REPLACE statement, which is basically the SQL
看起来 BerkeleyDB 被 Oracle 收购了,它没有在其网站上发布源代码? 最佳答案 Sleepycat 于 2006 年被 Oracle 收购。该产品继续在原始开源许可下可用,并继续得到增
我是一名优秀的程序员,十分优秀!