13

我想在 Python 中为 SQLite 使用 json1 扩展。根据官方文档,它应该是一个可加载的扩展。我从源代码中得到了 json1.c 文件,并按照官方说明将其编译为 json1.so ,没有任何错误。

$ gcc -g -fPIC -shared json1.c -o json1.so

当我尝试根据sqlite3 文档在 Python 2.7.12(和 3.5.2)中加载扩展时出现了问题。

>>> import sqlite3
>>> con = sqlite3.connect(":memory:")
>>> con.enable_load_extension(True)
>>> con.load_extension("./json1.so")

我收到以下回溯错误消息。我从包含 json1.so 文件的文件夹中运行 Python 解释器。尽管由于最后一个冒号似乎应该有更多信息,但以下是完整的错误消息。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.OperationalError: error during initialization:

在 Python 中实际上不可能使用 json1 作为可加载扩展吗?正如Charles Leifer在这篇博文中所解释的那样,我唯一的选择是重新编译 SQLite、pysqlite2 等吗?

编辑:

事实证明,我收到了错误,因为我的机器已经启用了这个和其他扩展。启用已启用扩展的操作触发了错误。到目前为止,我可以访问的所有 linux 计算机都已经在 Python 附带的 SQLite 中启用了 json1 和 fts5 扩展。您可以通过连接到 SQLite 数据库并运行以下查询来检查已使用哪些编译选项。

PRAGMA compile_options;
4

2 回答 2

5

您可以使用 python 3 运行 sqlite。这是在我的 mac 上对我有用的方法:

首先编译可加载扩展:

curl -O http://sqlite.org/2016/sqlite-src-3140100.zip 

unzip sqlite-src-3140100.zip

gcc -g -fPIC -dynamiclib sqlite-src-3140100/ext/misc/json1.c -o json1

然后在脚本中使用它:

import sqlite3
conn = sqlite3.connect('testingjson.db')

#load precompiled json1 extension
conn.enable_load_extension(True)
conn.load_extension("./json1")

# create a cursor
c = conn.cursor()

# make a table
# create table NAME_OF_TABLE (NAME_OF_FIELD TYPE_OF_FIELD);
c.execute('create table testtabledos (testfield JSON);')

# Insert a row of data into a table
c.execute("insert into testtabledos (testfield) values (json('{\"json1\": \"works\"}'));")

# Save (commit) the changes
conn.commit()

# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()

或在外壳中:

.load json1
CREATE TABLE test_table (id INTEGER, json_field JSON);
# insert data into test table
insert into test_table (id, json_field) values (1, json('{"name":"yvan"}'));
insert into test_table (id, json_field) values (2, json('{"name":"sara"}'));
#select json objects from the json column
select * from test_table where json_extract("json_field", '$.name') is not null;
1|{"name":"yvan"}
2|{"name":"sara"}

我希望这更容易。似乎加载扩展(而不是在创建时将它们构建到 sqlite 中)更有意义。我的最新问题是我似乎无法在 CentOS 6 上编译 json1 扩展。

我在这里写了一个指南:https ://github.com/SMAPPNYU/smapphowto/blob/master/howto_get_going_with_sqlite_json1.md

编辑:为了我的目的,我最终放弃了 json1。我现在只需通过提取我想要的字段将pysmap dump_to_csv用于基于列的csv,然后dump_to_sqlite_db从该csv 创建一个普通的sqlite db。见pysmap smapp_collection

于 2016-11-11T16:52:28.273 回答
4

对于仍在试图弄清楚如何从源代码构建 json1 扩展的任何人,这里是:

SQLite Source Repository下载最新版本的源代码后,解压缩,cd 到其文件夹并运行../configure

然后将以下内容添加到生成的Makefile

json1.dylib: json1.lo  
    $(LTCOMPILE) -c $(TOP)/ext/misc/json1.c  
    $(TCC) -shared -o json1.dylib json1.o  

make很挑剔,所以一定要在前面加上 TAB,$(LTCOMPILE)$(TCC)不是空格!

然后运行make json1.dylib

参考:https ://burrows.svbtle.com/build-sqlite-json1-extension-as-shared-library-on-os-x

于 2019-01-15T07:25:44.583 回答