小工具知识网

当前位置: 首页 > 行业知识 > 【Python百日进阶-Web开发-Peewee】Day283 - Peewee 的扩展(二)apsw/sqlcipher/postgresql

行业知识

【Python百日进阶-Web开发-Peewee】Day283 - Peewee 的扩展(二)apsw/sqlcipher/postgresql

2026-11-11 00:28:09 来源:互联网转载

文章目录

    • 13.4 apsw,一个高级的 sqlite 驱动程序
      • 13.4.1 如何使用 APSW 数据库
      • 13.4.2 apsw_ext API 说明
      • 13.5 Sqlcipher 后端
        • 13.5.1 sqlcipher_ext API 说明
        • 13.6 Postgresql 扩展
          • 13.6.1 JSON 支持
          • 13.6.2 hstore ���持

            13.4 apsw,一个高级的 sqlite 驱动程序

            该apsw_ext模块包含一个适合与 apsw sqlite 驱动程序一起使用的数据库类。

            ()

            APSW 项目页面:https /github.com/rogerbinns/apsw

            APSW 是一个非常简洁的库,它在 SQLite 的 C 接口之上提供了一个精简的包装器,从而可以使用 SQLite 的所有高级功能。

            ()

            以下是使用 APSW 的几个原因,摘自文档:

            • APSW 提供了 SQLite 的所有功能,包括虚拟表、虚拟文件系统、blob i/o、备份和文件控制。
            • 可以跨线程共享连接,而无需任何额外的锁定。
            • 事务由您的代码显式管理。
            • APSW 可以处理嵌套事务。
            • Unicode 被正确处理。
            • APSW 更快。

              有关 apsw 和 pysqlite 之间差异的更多信息,请查看apsw 文档。

              13.4.1 如何使用 APSW 数据库

              from apsw_ext import *db = APSWDatabase(':memory:')class BaseModel(Model):    class Meta:        database = dbclass SomeModel(BaseModel):    col1 = CharField()    col2 = DateTimeField()

              13.4.2 apsw_ext API 说明

              APSWDatabase扩展SqliteExtDatabase并继承了其高级功能。

              class APSWDatabase(database,**connect_kwargs )

              参数:

              • database ( string ) – sqlite 数据库的文件名
              • connect_kwargs – 打开连接时传递给 apsw 的关键字参数
                register_module( mod_name , mod_inst )

                提供一种全局注册模块的方法。有关详细信息,请参阅有关虚拟表的文档。

                参数:

                • mod_name ( string ) – 用于模块的名称
                • mod_inst ( object ) – 实现Virtual Table接口的对象
                  unregister_module( mod_name )

                  注销一个模块。

                  参数: 模组名称( string ) – 用于模块的名称

                  笔记

                  请务必使用模块中Field定义的子类apsw_ext ,因为它们将正确处理调整数据类型以进行存储。

                  例如,不要使用peewee.DateTimeField,请确保您正在导入和使用playhouse.apsw_ext.DateTimeField.

                  13.5 Sqlcipher 后端

                  笔记

                  尽管此扩展的代码很短,但尚未经过适当的同行评审,并且可能引入了漏洞。

                  另请注意,此代码依赖于sqlcipher3(python 绑定)和sqlcipher,其中的代码也可能存在漏洞,但由于这些是广泛使用的加密模块,我们可以预期那里的“短零日”。

                  13.5.1 sqlcipher_ext API 说明

                  class SqlCipherDatabase(database, passphrase, **kwargs)

                  SqliteDatabase存储加密数据库的子类。它没有使用标准sqlite3后端,而是使用sqlcipher3 : sqlcipher的python 包装器,而后者又是一个加密包装器sqlite3,因此 API与’s 相同,SqliteDatabase除了对象构造参数:

                  参数:

                  • database – 要打开 [或创建] 的加密数据库文件名的路径。
                  • passphrase – 数据库加密密码:至少应为 8 个字符长,但强烈建议在您的实现中强制执行更好的密码强度 标准。

                    如果该database文件不存在,它将通过从passhprase.

                    尝试打开现有数据库时,passhprase应与创建时使用的数据库相同。如果密码不正确,首次尝试访问数据库时将引发错误。

                    rekey(passphrase)

                    参数: passphrase( str ) – 数据库的新密码。

                    更改数据库的密码。

                    笔记

                    可以使用许多扩展 PRAGMA 来配置 SQLCipher。可以在SQLCipher 文档中找到 PRAGMA 列表及其描述。

                    例如,指定密钥派生的 PBKDF2 迭代次数(SQLCipher 3.x 中为 64K,SQLCipher 4.x 中默认为 256K):

                    # Use 1,000,000 iterations.db = SqlCipherDatabase('my_app.db', pragmas={'kdf_iter': 1000000})

                    要使用 16KB 的密码页面大小和 10,000 个页面的缓存大小:

                    db = SqlCipherDatabase('my_app.db', passphrase='secret!!!', pragmas={    'cipher_page_size': 1024 * 16,    'cache_size': 10000})  # 10,000 16KB pages, or 160MB.

                    提示用户输入密码的示例:

                    db = SqlCipherDatabase(None)class BaseModel(Model):    """Parent for all app's models"""    class Meta:        # We won't have a valid db until user enters passhrase.        database = db# Derive our model subclassesclass Person(BaseModel):    name = TextField(primary_key=True)right_passphrase = Falsewhile not right_passphrase:    db.init(        'testsqlcipher.db',        passphrase=get_passphrase_from_user())    try:  # Actually execute a query against the db to test passphrase.        db.get_tables()    except DatabaseError as exc:        # This error indicates the password was wrong.        if exc.args[0] == 'file is encrypted or is not a database':            tell_user_the_passphrase_was_wrong()            db.init(None)  # Reset the db.        else:            raise exc    else:        # The password was correct.        right_passphrase = True

                    另见:一个稍微复杂的例子。

                    13.6 Postgresql 扩展

                    postgresql 扩展模块提供了许多“postgres-only”功能,目前:

                    • json 支持,包括Postgres 9.4 的jsonb。
                    • hstore 支持
                    • server-side cursors 服务器端游标
                    • full-text search 全文检索
                    • ArrayField字段类型,用于存储数组。
                    • HStoreField字段类型,用于存储键/值对。
                    • IntervalField字段类型,用于存储timedelta对象。
                    • JSONField字段类型,用于存储 JSON 数据。
                    • BinaryJSONField 数据类型的jsonbJSON字段类型。
                    • TSVectorField字段类型,用于存储全文搜索数据。
                    • DateTimeTZField字段类型,时区感知的日期时间字段。

                      将来我想添加对更多 postgresql 功能的支持。如果您希望添加某个特定功能,请 打开 Github 问题。

                      警告

                      为了开始使用下面描述的功能,您需要使用扩展PostgresqlExtDatabase类而不是PostgresqlDatabase

                      下面的代码将假设您使用以下数据库和基本模型:

                      from playhouse.postgres_ext import *ext_db = PostgresqlExtDatabase('peewee_test', user='postgres')class BaseExtModel(Model):    class Meta:        database = ext_db

                      13.6.1 JSON 支持

                      peewee 对 Postgres 的原生 JSON 数据类型有基本的支持,格式为 JSONField. 从 2.4.7 版本开始,peewee 还支持 Postgres 9.4 二进制 jsonjsonb类型,通过BinaryJSONField.

                      警告

                      Postgres 从 9.2 开始原生支持 JSON 数据类型(在 9.3 中完全支持)。要使用此功能,您必须使用正确版本的 Postgres 和psycopg2 2.5 或更高版本。

                      要使用BinaryJSONField具有许多性能和查询优势的 ,您必须具有 Postgres 9.4 或更高版本。

                      笔记

                      您必须确保您的数据库是一个实例 PostgresqlExtDatabase才能使用JSONField。

                      下面是一个示例,说明如何使用 JSON 字段声明模型:

                      import jsonimport urllib2from playhouse.postgres_ext import *db = PostgresqlExtDatabase('my_database')class APIResponse(Model):    url = CharField()    response = JSONField()    class Meta:        database = db    @classmethod    def request(cls, url):        fh = urllib2.urlopen(url)        return cls.create(url=url, response=json.loads(fh.read()))APIResponse.create_table()# Store a JSON response.offense = APIResponse.request('http://crime-api.com/api/offense/')booking = APIResponse.request('http://crime-api.com/api/booking/')# Query a JSON data structure using a nested key lookup:offense_responses = APIResponse.select().where(    APIResponse.response['meta']['model'] == 'offense')# Retrieve a sub-key for each APIResponse. By calling .as_json(), the# data at the sub-key will be returned as Python objects (dicts, lists,# etc) instead of serialized JSON.q = (APIResponse     .select(       APIResponse.data['booking']['person'].as_json().alias('person'))     .where(APIResponse.data['meta']['model'] == 'booking'))for result in q:    print(result.person['name'], result.person['dob'])

                      其BinaryJSONField工作原理与常规相同,支持相同的操作JSONField,但提供了几个额外的操作来测试遏制。使用二进制 json 字段,您可以测试您的 JSON 数据是否包含其他部分 JSON 结构 ( contains(), contains_any(), contains_all()),或者它是否是较大 JSON 文档的子集 ( contained_by())。

                      有关更多示例,请参阅下面的JSONField和 BinaryJSONFieldAPI 文档。

                      13.6.2 hstore 支持

                      Postgresql hstore 是一个嵌入式键/值存储。使用 hstore,您可以将任意键/值对与结构化关系数据一起存储在数据库中。

                      要使用hstore,您需要在实例化时指定一个附加参数PostgresqlExtDatabase:

                      # Specify "register_hstore=True":db = PostgresqlExtDatabase('my_db', register_hstore=True)

                      目前该postgres_ext模块支持以下操作:

                      • 存储和检索任意字典
                      • 按键或部分字典过滤
                      • 更新/添加一个或多个键到现有字典
                      • 从现有字典中删除一个或多个键
                      • 选择键、值或 zip 键和值
                      • 检索一段键/值
                      • 测试密钥是否存在
                      • 测试一个键是否具有非 NULL 值

上一篇:买的商品房还没有备案怎么退款

下一篇:电脑怎么连共享服务器?