跳转到主要内容

将Python字典打包/解包到/从MariaDB的动态列格式。

项目描述

https://img.shields.io/github/workflow/status/adamchainz/mariadb-dyncol/CI/main?style=for-the-badge https://img.shields.io/pypi/v/mariadb-dyncol.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

未维护(2022-12-07)

由于该包从未流行,我停止了该包的维护。自从MariaDB添加了JSON支持,最好使用它进行可移植性,而不是自定义动态列格式。如果您想接管该包的维护,请给我发邮件。


将Python dict打包/解包到/从MariaDB的动态列格式。

快速示例

>>> mariadb_dyncol.pack({"key": "value"})
b'\x04\x01\x00\x03\x00\x00\x00\x03\x00key!value'
>>> mariadb_dyncol.unpack(mariadb_dyncol.pack({"key": "value"}))
{'key': 'value'}

安装

使用pip

python -m pip install mariadb-dyncol

Python 3.7到3.11受支持。


在Django项目中工作? 查看我的书籍 Boost Your Django DX,该书籍涵盖了许多改进您开发体验的方法。


功能

  • 从Python到SQL的合理类型映射

  • 已针对MariaDB的示例进行测试,包括使用hypothesis(它非常棒并发现了许多错误)进行的属性/模糊测试

为什么?

将数据添加到动态列字段的常规方式是使用COLUMN_CREATE函数及其相关函数。这允许你做类似的事情

INSERT INTO mytable (attrs) VALUES (COLUMN_CREATE('key', 'value'))

不幸的是,Django ORM受限制,不能在所有情况下使用此类数据库函数,至少在Django 1.9之前是这样。当我在我自己的项目django-mysql中实现动态列字段时,遇到了这种限制,促使我创建了这个库。

通过预先打包动态列,上述查询可以直接插入数据块

INSERT INTO mytable (attrs) VALUES (X'0401000300000003006B65792176616C7565')

除了使用Django ORM更容易实现之外,这种在Python中打包/解包动态列的方法还有一些优点

  • 所有数据类型在Python中都得到了适当的保留。MariaDB提供拉回动态列字段所有值的唯一方法是调用COLUMN_JSON,但JSON只支持字符串和整数。此外,COLUMN_JSON的深度限制为10,但格式实际上没有限制。

  • 打包/解包动态列的CPU开销从您的数据库服务器转移到您的(可能是更可扩展的)客户端。

API

所有函数和名称都可以作为mariadb_dyncol模块的属性访问,您可以使用import mariadb_dyncol导入该模块。

pack(mapping)

将给定的映射(一个dict)打包成MariaDB动态列格式,并以字节字符串的形式返回(Python 3的bytes,Python 2的str)。这适用于作为常规查询的一部分插入到表中。

dict的键必须全部是Unicode字符串,而值必须全部是支持的数据类型之一

  • int-(2 ** 32) + 1(2 ** 64) - 1之间(Python 2:也支持long

  • str最多4GB,以UTF-8编码(Python 2:支持unicode

  • float - 除了NaN+/- inf之外的任何内容

  • datetime.datetime - 支持完整范围

  • datetime.date - 支持完整范围

  • datetime.time - 支持完整范围

  • 任何符合这些规则的dict,允许嵌套键。除了MariaDB的COLUMN_JSON函数限制深度为10之外,没有嵌套限制

请注意,这不支持MariaDB也支持(并自然会映射到Python的Decimal)的DECIMAL类型 - 打包/解包稍微有点复杂,尽管确实可能,而且欢迎提交pull请求。如果您尝试打包一个Decimal,将引发DynColNotSupported异常。

有关UTF-8编码的列名的其他限制,请参阅MariaDB文档

  • 列名的最大长度为16383字节

  • 所有列名的最大长度(在嵌套层次结构中的一级)为65535字节

所有其他不受支持的类型将引发DynColTypeError。超出范围的值将引发DynColValueError

示例

>>> mariadb_dyncol.pack({"a": 1})
b'\x04\x01\x00\x01\x00\x00\x00\x00\x00a\x02'
>>> mariadb_dyncol.pack({"a": "💩"})
b'\x04\x01\x00\x01\x00\x00\x00\x03\x00a!\xf0\x9f\x92\xa9'

unpack(bytestring)

将MariaDB动态列数据编码的字节字符串解包成dict;您可以期望返回的类型如上所述。这适用于直接从MariaDB获取数据并在Python中解码,而不是使用MariaDB的COLUMN_JSON函数,保留JSON丢弃的类型。

如上所述,不支持DECIMAL值,解包将引发DynColNotSupported。此外,字符串仅使用MySQL字符集utf8utf8mb4解码;具有其他字符集的字符串也将引发DynColNotSupported

不受支持的列格式,例如旧的MariaDB编号动态列格式或损坏的数据,将引发DynColValueError

示例

>>> mariadb_dyncol.unpack(b"\x04\x01\x00\x01\x00\x00\x00\x03\x00a!\xf0\x9f\x92\xa9")
{"a": "💩"}
>>> mariadb_dyncol.unpack(b"\x04\x01\x00\x01\x00\x00\x00\x00\x00a\x02")
{"a": 1}

项目详情


下载文件

下载您平台对应的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

mariadb-dyncol-3.6.1.tar.gz (12.6 kB 查看哈希值)

上传时间 源代码

构建分布

mariadb_dyncol-3.6.1-py3-none-any.whl (8.8 kB 查看哈希值)

上传时间 Python 3

支持者

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页面