一种基于json的表数据格式
ljson的Python项目详细描述
内容
What is ljson?
ljson试图创建一个适合 现代数据处理的需要。它是设计用来工作的 比通常的json快,但是保持简单但是 优雅的对象表示。
可以使用ljson代替纯json来增加 访问大数据集时的性能。
Why ljson?
有一种lot数据存储格式:xml, json、csv、sql、nosql、二进制压缩、gnu-db、…
其中一些是为了存储完整的数据库(SQL, nosql,…)和一些是用来存储表的。以及 当然有json和xml。它们可以用来储存 更复杂的对象,是人类可读的,数据被存储 只有一个文件。
但他们有一个问题:如果一个人想改变 文件中的数据他必须读取完整的文件并存储 他内存中的所有数据。这很慢,也许不可能 (big data)而且不安全。如果流程无法完成 操作正确这可能会损坏所有数据。
ljson试图通过混合使用csv(line 基于)和json(基于对象):
每一行都是一个对象。如果要添加另一个对象 他只是以追加模式打开文件并添加一行。如果 一行已损坏文件的其余部分仍然有效。
也可以通过 逐行读取文件。
特别是异步操作可以很容易地执行, 因为文件的主要部分保持不变(除非 改变对象。然后必须重新写入文件)。
Design
ljson被设计成存储在文件中,定义 ljson文件的值是:
<ljson_file> = [<header>\n]<ljson_content> <ljson_content> = <json_object>{\n<json_object>}
<json_object>可以是任何json对象,如 json.org。
Header
头是一个特殊的json对象,它描述数据 在档案里。标题必须采用以下格式:
<header> = "{ \"__type__\": \"header\"," <fieldname>": {" "\"type\":" <type>", \"modifiers\":" <modifiers> "}" <type> = "\"int\"" | "\"str\"" | "\"bool\"" | "\"float\"" | "\"null\"" | "\"bytes\"" <modifiers> = "[" [<modifier> {","<modifier>}] "]" <modifier> = "\"unique\"" | "\"not null\""
头是磁盘上实现所必需的。
Datatypes
如果使用ljson,则仅限于以下python 数据类型(及其ljson类型):
- int:"int"
- str:"str"
- bool:"bool"
- float:"float"
- bytes:"bytes"
- dict:"json"
- list:"json"
因为可以将所有数据类型转换为 这些可以存储任何类型的数据。
Usage
Without a Python Module
ljson设计为在没有任何第三方python的情况下工作 模块。可以使用python内置的读取ljson数据 json模块:
>>> import json >>> ljson = '{"id": 1, "name": "foo"}\n{"id": 2, "name": "bar"}' >>> for line in ljson.split("\n"): ... print(json.loads(line)) ... {'name': 'foo', 'id': 1} {'name': 'bar', 'id': 2}
这应该是访问ljson的首选方法 数据,如果需要所有数据。
如果想访问特定字段,最好使用 ljson python模块:
With the ljson Module
如果需要的话,使用ljson模块是简单有效的 只访问一些字段,而不是整个文件。
有两种基本实现:ljson.base.mem 将文件内容加载到RAM中。速度快了很多 支持没有头的文件,并且可以构造 没有文件的桌子。
第二个实现是ljson.base.disk。这个 实现不会将任何数据加载到RAM中。如果你是 访问你应该访问的大型集我使用这个实现。
创建表很简单(至少对于内存来说 表格):
>>> import ljson >>> header = ljson.Header({"id": {"type": "int", "modifiers":["unique"]}, "name": {"type": "str", "modifiers": []}}) >>> table = ljson.Table(header, [{"id": 1, "name": "foo"}, {"id": 2, "name": "bar"}, {"id": 3, "name": "bar"}])
可以使用python的内置^{tt19}访问项$ 以及__setitem__:
>>> table[{"id": 1}]["name"] ['foo'] >>> list(table[{"id": 1}]) [{'name': 'foo', 'id': 1}]
表“index”必须是dict,这允许访问 非唯一行,如下:
>>> list(table[{"name":"bar"}]) [{'id': 2, 'name': 'bar'}, {'id': 3, 'name': 'bar'}]
Using ljson to store data
使用ljson存储数据非常简单:
>>> from io import StringIO >>> fout = StringIO() >>> table.save(fout) >>> fout.seek(0) 0 >>> fout.read() '{"name": {"type": "str", "modifiers": []}, "__type__": "header", "id": {"type": "int", "modifiers": ["unique"]}}\n{"name": "foo", "id": 1}\n{"name": "bar", "id": 2}\n{"name": "bar", "id": 3}' >>> fout.seek(0) 0 >>> table2 = ljson.Table.from_file(fout) >>> list(table2) [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 3, 'name': 'bar'}]
读写csv文件也很简单:
>>> from ljson.convert.csv import table2csv, csv2table >>> fout = StringIO() >>> table2csv(table, fout) >>> fout.seek(0) 0 >>> fout.read() 'id,name\r\n1,foo\r\n2,bar\r\n3,bar\r\n' >>> fout.seek(0) 0 >>> table2 = csv2table(fout, types = {"id": "int", "name":"str"}) >>> list(table2) [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 3, 'name': 'bar'}]
Todos
- 将字节存储为b64
- 修复SQL字节表示法