{"id":20724894,"url":"https://github.com/cozodb/pycozo","last_synced_at":"2025-08-21T05:31:57.687Z","repository":{"id":64061022,"uuid":"551375812","full_name":"cozodb/pycozo","owner":"cozodb","description":"The Python client and Jupyter helper for CozoDB","archived":false,"fork":false,"pushed_at":"2024-10-27T16:10:36.000Z","size":80,"stargazers_count":52,"open_issues_count":8,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-08T04:51:17.403Z","etag":null,"topics":["cozo","cozoscript","jupyter","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cozodb.png","metadata":{"files":{"readme":"README-zh.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-10-14T09:31:32.000Z","updated_at":"2025-03-21T03:11:50.000Z","dependencies_parsed_at":"2023-12-11T10:43:44.007Z","dependency_job_id":null,"html_url":"https://github.com/cozodb/pycozo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cozodb/pycozo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozodb%2Fpycozo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozodb%2Fpycozo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozodb%2Fpycozo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozodb%2Fpycozo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cozodb","download_url":"https://codeload.github.com/cozodb/pycozo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozodb%2Fpycozo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271430755,"owners_count":24758365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cozo","cozoscript","jupyter","python"],"created_at":"2024-11-17T04:16:32.629Z","updated_at":"2025-08-21T05:31:57.442Z","avatar_url":"https://github.com/cozodb.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# PyCozo\n\n[![pypi](https://img.shields.io/pypi/v/pycozo)](https://pypi.org/project/pycozo/)\n\n[Cozo](https://www.cozodb.org) 数据库的 Python 库，支持在 Jupyter 笔记本中使用。\n\n本文叙述的是如何安装设置库本身。有关如何使用 CozoDB（CozoScript）的信息，见 [文档](https://docs.cozodb.org/zh_CN/latest/index.html) 。\n\n## 安装\n\n```bash\npip install \"pycozo[embedded,requests,pandas]\"\n```\n\n如果想通过嵌入模式使用 CozoDB，则必须指定 `embedded` 选项；如果想通过 HTTP 请求模式连接 CozoDB 服务器，则必须指定 `requests` 选项。`pandas` 选项会安装 `pandas` 包，并在查询返回结果时将其转换为 Pandas 数据帧。在使用 Jupyter 中使用 pycozo 时建议打开 `pandas` 选项。\n\n## Python 客户端\n\n首先引入模块：\n\n```python\nfrom pycozo.client import Client\n```\n\n### 构建数据库\n\n基于纯内存非值久化的存储引擎的数据库：\n\n```python\nclient = Client()\n```\n\n基于 SQLite 引擎的数据库（占用资源小）：\n\n```python\nclient = Client('sqlite', 'file.db')\n```\n\n基于 RocksDB 引擎的数据库（性能强劲，支持高并发）：\n\n通过 HTTP 连接独立的 CozoDB 服务：\n\n```python\nclient = Client('http', options={'host': 'http://127.0.0.1:9070'})\n```\n\n如果服务器地址不是本地回环地址，则需要传入验证令牌：\n\n```python\nclient = Client('http', options={'host': ..., 'auth': ...})\n```\n\n验证令牌 `auth` 的内容在运行服务器时会有提示告诉如何获得。\n\n数据库使用完后需要手动关闭：\n\n```python\nclient.close()\n```\n\n如果不关闭而仅仅是将 `client` 变量 `del`，则相关的原生资源不会被释放。多次关闭同一个数据库不会报错。\n\n### 查询\n\n```python\nres = client.run(SCRIPT)\n```\n\n需要绑定变量时：\n\n```python\nres = client.run('?[] \u003c- [[$name]]', {'name': 'Python'})\n```\n\n如果 `pandas` 模块可用，则结果通过数据帧的形式返回。如果你安装了 `pandas` 但是不希望返回数据帧，则可以在创建数据库时使用 `dataframe=False` 选项，在此情况下返回的是一个字典，字典里的 `'rows'` 字段包含返回行，而 `'header'` 包含行的标头。\n\n当查询出错时，会抛出异常，可以通过以下方式显示更加友好的异常信息：\n\n```python\ntry:\n    res = client.run('BAD!')\nexcept Exception as e:\n    print(repr(e))\n```\n\n`Client` 是线程安全的，但是多个不同的进程不可以同时访问同一个嵌入式数据库（接入同一个独立服务是可以的）。\n\n在嵌入模式下，`Client` 执行查询时会释放 [GIL](https://wiki.python.org/moin/GlobalInterpreterLock) ，因此与原生的 Python 程序不同，多线程查询确实会并行查询。\n\n嵌入式的数据库与 Python 运行时直接交换数据（不会经过转化为 JSON 的过程）。因此你可以直接传入字节数组为参数，且查询返回的字节数组也不需要解码。\n\n\n### 其它操作\n\n`Client` 类有有以下方法：`export_relations`、`import_relations`、`backup`、`restore`、 `import_from_backup`，其作用见 [此文档](https://docs.cozodb.org/zh_CN/latest/nonscript.html) 。\n\n### 多语句事务\n\n你可以将同一个事务中的多个查询语句与 Python 代码交叉执行，如下例：\n\n```python\ntx = client.multi_transact(True) # False 或不传参数代表只读事务\n\ntx.run(':create a {a}')\ntx.run('?[a] \u003c- [[1]] :put a {a}')\ntry:\n    tx.run(':create a {a}')\nexcept:\n    pass\n\ntx.run('?[a] \u003c- [[2]] :put a {a}')\ntx.run('?[a] \u003c- [[3]] :put a {a}')\ntx.commit() # `tx.abort()` 会舍弃所有更改并删除事务相关联的系统资源\n\nr = client.run('?[a] := *a[a]')\nassert r['rows'] == [[1], [2], [3]]\n```\n\n事务结束时，你 **必须** 调用 `tx.commit()` 或 `tx.abort()` ，否则系统资源会泄露。\n\n### 更改回调\n\n你可以设置在存储表被更改时会被调用的回调函数。例子：\n\n```python\n# 回调函数必须接受三个参数\ndef cb(op_name, new_rows, old_rows):\n    # op_name 是 'Put' 或 'Rm'\n    # new_rows 是一个包含列表的列表，包含新的行（要求插入或删除的行）\n    # old_rows 是一个包含列表的列表，包含旧的行（被更改的行的旧值，或被删除的行）\n    pass\n\n# 回调函数在存储表 test_rel 被更改时会被调用\ncb_id = client.register_callback('test_rel', cb)\n\n# 程序的其它逻辑\n\n# 注册回调函数时返回的值可以用来删除注册\n# client.unregister_callback(cb_id)\n```\n\n### 自定义固定规则\n\n你可以使用 Python 来自定义固定规则。例子：\n\n```python\n# 固定规则的实现，必须接受两个参数\ndef rule_impl(inputs, options):\n    # inputs 是一个列表的列表的列表，含有固定规则被调用时传入的表\n    # option 是一个字符串键的字典，包含被调用时传入的参数\n    \n    # 必须返回列表（或元组）的列表作为固定规则的返回表。如果无法返回（比如参数错误等），直接抛出异常即可。\n    return [('Nicely',), ('Done!',)]\n\n# 注册固定规则。第二个参数是返回列表的列数，必须与实现中返回的列数相同。\nclient.register_fixed_rule('Custom', 1, rule_impl)\n\nr = client.run(\"\"\"\n    rel[u, v, w] \u003c- [[1,2,3],[4,5,6]]\n    ?[] \u003c~ Custom(rel[], x: 1, y: null)\n\"\"\")\nassert r['rows'] == [['Done!'], ['Nicely']]\n\n# 取消注册的固定规则\nclient.unregister_fixed_rule('Custom')\n```\n\n## Jupyter 工具\n\n通过 [魔法命令](https://ipython.readthedocs.io/en/stable/interactive/magics.html) 可激活两种不同的 Jupyter 工具，两种工具都可以让你直接查询数据库。第一种是：\n\n```\n%load_ext pycozo.ipyext_direct\n```\n\n在这种模式下，所有单元格都默认会被作为 CozoScript 执行，除非整个单元格以 `%` 开头。如果单元格的第一行的内容是 `%%py`，则余下的行作为 Python 代码执行。\n\n第二种是：\n\n```\n%load_ext pycozo.ipyext\n```\n\n在这种模式下，只有在单元格第一行的内容为 `%%cozo` 时，余下的内容才会被作为 CozoScript 执行，因此这种模式适用于 Python 代码比 CozoScript 多的情况。\n\n执行查询之前，先要打开数据库。如果你安装了嵌入模式而没做额外的事情，则默认会打开纯内存非持久化的数据库。你可以执行\n\n```\n%cozo_open \u003cENGINE\u003e, \u003cPATH\u003e\n```\n\n来选择打开哪种数据库以及数据文件的路径。这里 `\u003cENGINE\u003e` 可以是 `'sqlite'`、`'rocksdb'` 或 `'mem'`。\n\n如果需要连接到独立的服务，则执行\n\n```\n%cozo_host http://\u003cADDRESS\u003e:\u003cPORT\u003e\n%cozo_auth \u003cAUTH_STRING\u003e\n```\n\n若 `\u003cADDRESS\u003e` 指向本地回传地址，则 `\u003cAUTH_STRING\u003e` 可省略。在其它情况下，如何获取其需要的值请参见 [这里](https://github.com/cozodb/cozo/blob/main/cozoserver/README-zh.md)（或 [国内镜像](这里](https://gitee.com/cozodb/cozo/tree/main/cozoserver)）.\n\n还有一些其它的魔法命令可以使用：\n\n* `%cozo_run_file \u003cPATH_TO_FILE\u003e` 运行一个包含 CozoScript 内容的本地文件。\n* `%cozo_run_string \u003cVARIABLE\u003e` 运行一个变量或常量中包含的 CozoScript 文本内容。\n* `%cozo_set \u003cKEY\u003e \u003cVALUE\u003e` 将查询参数 `\u003cKEY\u003e` 设为 `\u003cVALUE\u003e`，设置的参数可以在接下来的查询中使用。\n* `%cozo_set_params \u003cPARAM_MAP\u003e` 以给出的字典替换当前所有的参数。\n* `%cozo_clear` 清空当前设置的所有参数。\n* `%cozo_params` 返回当前设置的所有参数。\n\n## 编译\n\n这个库本身是纯 Python 写成的，但是其 `embedded` 选项依赖于 `cozo-embedded` 库，[在此](https://github.com/cozodb/cozo/blob/main/cozo-lib-python/README-zh.md)（[国内镜像](https://gitee.com/cozodb/cozo/tree/main/cozo-lib-python)）有叙述。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozodb%2Fpycozo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcozodb%2Fpycozo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozodb%2Fpycozo/lists"}