如何在SQLAlchemy中加载SQLite3扩展?

时间:2018-02-18 11:25:24

标签: python sqlite sqlalchemy flask-sqlalchemy

我使用SQLAlchemy在我的应用程序中构建了一个SQLite扩展(即.so库)。这是一个Flask应用程序,但我不认为Flask在这里发挥作用。

可以从CLI加载扩展程序,似乎可以正常工作:

$ sqlite3

SQLite version 3.20.1 2017-08-24 16:21:36
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .load ./libSqliteIcu.so

但我需要在我的应用中执行此操作。 Python文档中有一个例子:

import sqlite3

con = sqlite3.connect(":memory:")

# enable extension loading
con.enable_load_extension(True)

# Load the fulltext search extension
con.execute("select load_extension('./fts3.so')")

但在我的应用中,我必须使用db访问数据库:

db = flask_sqlalchemy.SQLAlchemy()

我可以将最后一个语句重写为:

db.session.execute('select load_extension("./libsqliteicu.so")')

但它失败了"未授权"错误。

如何致电enable_load_extension()或以其他方式成功加载附加信息?

1 个答案:

答案 0 :(得分:1)

经过一些搜索和测试,并根据各种来源,这对我有用。这就是我所能说的代码质量。我发布它只是因为它可能会帮助某人。如果您发现问题,请随时发表评论。

from sqlalchemy.event import listen

# initialization routine
# app: this Flask application
# db: the database, see the question 
db_collate = 'sk_SK.UTF-8'   # Slovak language for example
def load_extension(dbapi_conn, unused):
    dbapi_conn.enable_load_extension(True)
    dbapi_conn.load_extension('/path/tolibSqliteIcu.so')
    dbapi_conn.enable_load_extension(False)
    dbapi_conn.execute("SELECT icu_load_collation(?, 'ICU_EXT_1')", (db_collate,))
with app.app_context():
    listen(db.engine, 'connect', load_extension)

和用法:

from sqlalchemy.sql.expression import collate

...query.order_by(collate(Table.column, 'ICU_EXT_1'))

名称ICU_EXT_1完全是任意的。