oodb


Nameoodb JSON
Version 1.0.3 PyPI version JSON
download
home_pageNone
Summary面向对象数据库 —— 引入了 Python 中类的特性,如:继承、重写、方法、动态属性等。
upload_time2024-07-28 23:47:23
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseNone
keywords oodbms oodbs oodb
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 项目描述

面向对象数据库 —— 引入了 Python 中类的特性,如:继承、重写、方法、动态属性等。

该软件使用 MongoDB 来持久化数据,并在 Python 层面利用软件算法模拟出继承等特性。

如果你不需要使用继承、重写等特性,而只是需要一个用来操作 MongoDB 的 ODM,我们为你准备了另一款更合适的工具 —— [oomongo](https://pypi.org/project/oomongo/) 。

# 作者

江南雨上

[主页](https://lcctoor.com/index.html) \| [Github](https://github.com/lcctoor) \| [PyPi](https://pypi.org/user/lcctoor) \| [微信](https://lcctoor.com/cdn/WeChatQRC.jpg) \| [邮箱](mailto:lcctoor@outlook.com) \| [捐赠](https://lcctoor.com/cdn/DonationQRC-0rmb.jpg)

# Bug提交、功能提议

你可以通过 [Github-Issues](https://github.com/lcctoor/arts/issues)、[微信](https://lcctoor.com/cdn/WeChatQRC.jpg) 与我联系。

# 安装

```
pip install oodb
```

# 教程

本文将以简洁的方式向你介绍核心知识,而不会让你被繁琐的术语所淹没。

## 导入

```python
from pymongo import MongoClient
from oodb import OOM, Row, mc, mf, mo, mpy
```

## 创建OOM

```python
class OOM_2(OOM):
    def mkconn(self):
        return MongoClient(host='localhost', port=27017)  # MongoDB 连接器,用来写入和读取数据

oom = OOM_2()          # 账户OOM
db = oom['泉州市']      # 库OOM
sheet = db['希望小学']  # 表OOM
```

## 基础功能 —— 增、删、改、查

【增、删、改、查】的方法名称分别为:insert、delete、update、find 。

### 示例

```python
row1 = {'姓名':'小一', '年龄':11, '幸运数字':[1, 2, 3], '成绩':{'语文':81, '数学':82}}
row2 = {'姓名':'小二', '年龄':12, '幸运数字':[2, 3, 4], '成绩':{'语文':82, '数学':83}}
row3 = {'姓名':'小三', '年龄':13, '幸运数字':[3, 4, 5], '成绩':{'语文':83, '数学':84}}
row4 = {'姓名':'小四', '年龄':14, '幸运数字':[4, 5, 6], '成绩':{'语文':84, '数学':85}}
row5 = {'姓名':'小五', '年龄':15, '幸运数字':[5, 6, 7], '成绩':{'语文':85, '数学':86}}
row6 = {'姓名':'小六', '年龄':16, '幸运数字':[6, 7, 8], '成绩':{'语文':86, '数学':87}}
```

|    功能    | 代码                                                            |                               备注                               |
| :---------: | --------------------------------------------------------------- | :--------------------------------------------------------------: |
| 增(1 条) | sheet.insert( row1 )                                            |                                /                                |
| 增(批量) | sheet.insert( row2, row3 )                                      |                                /                                |
|     删     | sheet.delete( )                                                 |                                /                                |
|     改     | sheet.update( {'年龄': 100} )                                   |                                /                                |
|     查     | for  row  in  sheet.find( ):<br />     print( row['姓名'] ) | find 方法返回的是一个迭代器,因此需要使用 for 循环获取 row 对象 |

删除、修改、查询时,可传递 limit 参数来限制行数:

| 功能 | 代码                                                                     |
| :--: | ------------------------------------------------------------------------ |
|  删  | sheet.delete( limit=10 )                                                 |
|  改  | sheet.update( {'年龄': 100}, limit=10 )                                 |
|  查  | for  row  in  sheet.find( limit=10 ):<br />     print( row['姓名'] ) |

### 新增时,查看分配到的主键:

```python
row1 = {'姓名':'小一', '年龄':11, '幸运数字':[1, 2, 3], '成绩':{'语文':81, '数学':82}}
row2 = {'姓名':'小二', '年龄':12, '幸运数字':[2, 3, 4], '成绩':{'语文':82, '数学':83}}
row3 = {'姓名':'小三', '年龄':13, '幸运数字':[3, 4, 5], '成绩':{'语文':83, '数学':84}}

r1 = sheet.insert( row1 )
r2 = sheet.insert( row2, row3 )
```

方法1:使用 insert 添加数据成功后,row1~row3 已各自多了一个叫‘_id’的键,该键的值即分配到的主键。

方法2:

```python
r1.inserted_id
r2.inserted_ids
```

## 继承

让我们以 iPhone15 为例子来讲解【继承】。

### 新增一个【128G-黑色】版本的对象

我们发现,iPhone15 的不同版本是由【性能】和【外观】这两个维度组合而成的。因此,假如我们要新增一个【128G-黑色】版本的对象,我们可以这样做:

1、创建 基础数据、128G性能数据、黑色外观数据 三条数据:

```python
info_base = {'操作系统': 'iOS', 'CPU型号': 'A16', '屏幕尺寸': '6.1英寸'}
info_128G = {'内存': '128G', '价格': 4849}
info_黑 = {'边框颜色': '黑', '后盖颜色': '黑'}
```

2、把这三条数据插入到数据库,并获取对应的 _id 值:

```python
[id_base, id_128G, id_黑] = sheet.insert( info_base, info_128G, info_黑 ).inserted_ids
```

3、创建【128G-黑色】版本数据,插入到数据库,并获取对应的 _id 值:

```python
id_128G_黑 = sheet.insert({'版本名称': '128G-黑色'}, bases=[id_base, id_128G, id_黑]).inserted_id
```

查询【128G-黑色】版本对象的信息:

```python
row_128G_黑 = next( sheet[mc.版本名称 == '128G-黑色'].find() )

for key in ('版本名称', '操作系统', '内存', '边框颜色'):  # row_128G_黑 继承了 row_base, row_128G, row_黑, 因此具有它们的属性及其值
    print(row_128G_黑[key])

# >>> 128G-黑色
# >>> iOS
# >>> 128G
# >>> 黑
```

### 新增一个【128G-白色】版本的对象

```python
# 创建【白色外观】数据,插入到数据库,并获取对应的 _id 值:
id_白 = sheet.insert({'边框颜色': '白', '后盖颜色': '白'}).inserted_id

# 创建【128G-白色】版本数据,插入到数据库,并获取对应的 _id 值:
id_128G_白 = sheet.insert({'版本名称': '128G-白色'}, bases=[id_白, id_128G_黑]).inserted_id
```

查询【128G-白色】版本对象的信息:

```python
row_128G_白 = next( sheet[mc.版本名称 == '128G-白色'].find() )

for key in ('版本名称', '操作系统', '内存', '边框颜色'):
    print(row_128G_白[key])

# >>> 128G-白色
# >>> iOS
# >>> 128G
# >>> 白
```

### 属性查找顺序

在以上示例中,当我们新增【128G-白色】版本对象时,继承了 `row_白` 和 `row_128G_黑` ,这两个父对象都具有 `边框颜色` 属性,前者的该属性值为“白”,后者的该属性值为“黑”。最后,当我们打印 `row_128G_白` 对象的 `边框颜色` 属性时,打印出来的结果为 `白` 。

当一个对象继承自多个父对象,并且对于某一属性,这些父对象的该属性值各不相同时,子对象在表现该属性值时,会遵循【C3线性化算法】:

1、首先,子对象会在自身的属性中查找该属性,如果找到了,则立即返回该属性值。

2、如果在自身的属性中找不到该属性,则会按照从左往右的顺序,先从左边第 1 个父对象中查找,如果查找不到则再从第 2 个父对象中查找……直到在某个父对象中找到该属性时,则立即返回属性值。

## 重写

假如苹果公司与中国联通公司合作,推出了【128G-白色-联通合作】版本的 iPhone15 ,其各方面参数与【128G-白色】版本唯一的区别就是版本名称改成了“128G-白色-联通合作”,此时,我们可以利用【重写】的特性方便地新增一个【128G-白色-联通合作】版本的对象:

```python
id_128G_白_联通合作 = sheet.insert({'版本名称': '128G-白色-联通合作'}, bases=[id_128G_白]).inserted_id
```

在此例中,我们在新增 `row_128G_白_联通合作` 对象时,继承了 `row_128G_白` 对象,并重写了 `版本名称` 属性。

## 方法

让我们定义一个方法:该方法接收一个 `name` 参数,然后返回一个字符串 —— `[<当前时间>] 你好,<name>!我是【<版本名称>】版本的 iPhone15,很高兴成为你的移动助理!` 。

```python
# 创建对象方法
@mpy.method
def say_hello(self: 'Row', name: 'str'):
    import time
    版本名称 = self['版本名称']
    return f"[{int(time.time())}] 你好,{name}!我是【{版本名称}】版本的 iPhone15,很高兴成为你的移动助理!"

# 将对象方法赋值给基对象base, 它的子孙对象都将继承此方法
base_obj = next( sheet[mc._id == id_base].find() )
base_obj.update({'say_hello': say_hello})

# 调用对象方法
for _id in [id_128G_黑, id_128G_白, id_128G_白_联通合作]:
    obj = next( sheet[mc._id == _id].find() )
    say_hello = obj['say_hello']
    print(say_hello('程序猿'))

# >>> [1709654174] 你好,程序猿!我是【128G-黑色】版本的 iPhone15,很高兴成为你的移动助理!
# >>> [1709654174] 你好,程序猿!我是【128G-白色】版本的 iPhone15,很高兴成为你的移动助理!
# >>> [1709654174] 你好,程序猿!我是【128G-白色-联通合作】版本的 iPhone15,很高兴成为你的移动助理!
```

### 讲解

1、使用 `@mpy.method` 装饰一个普通函数,该函数就会变成对象方法。

2、注意到这行代码 `def say_hello(self: 'Row', name: 'str'):` 中, `'Row'` 和 `'str'` 被加了引号 —— 当我们为对象方法的参数做类型提示时,必须以字符串的格式。以下这种方式是错误的: `def say_hello(self: Row, name: str):` 。当然,类型提示只是用来让编辑器提示代码的,它可有可无,不是必要的。

3、可以在对象方法内导入并使用任何【标准库】和【第三方包】。

4、调用对象方法时,既可以使用位置传参,也可以使用关键词传参。例如,这两种方式都是可行的: `say_hello('程序猿')` 、 `say_hello(name='程序猿')` 。

5、对象方法是以人类易读的文本格式存储在 MongoDB 中的([查看图示](https://lcctoor.com/oodb/oa_/对象方法.png)),可直接通过 Navicat 等管理工具灵活修改。

## 动态属性

让我们用一个统计学生总数的案例来讲解【动态属性】。

```python
# 新增四个班级对象
C1 = sheet.insert({'班级编号': 1, '学生数量': 10}).inserted_id
C2 = sheet.insert({'班级编号': 2, '学生数量': 20}).inserted_id
C3 = sheet.insert({'班级编号': 3, '学生数量': 30}).inserted_id
C4 = sheet.insert({'班级编号': 4, '学生数量': 40}).inserted_id

# 创建一个获取学生总数量的动态属性值
@mpy.dynamic(C1, C2, id3=C3, id4=C4)
def get_students_count(self: 'Row', id1, id2, id3, id4):
    from oodb import Row  # Row 在实例化时需要接收两个参数: (parent: Sheet, _id)
    rows = [Row(parent=self.parent, _id=x) for x in (id1, id2, id3, id4)]
    return sum( [x['学生数量'] for x in rows] )

# 新增一个年级对象,并将【动态属性值】赋值给【学生总数量】属性
gid = sheet.insert({'年级': '五年级', '学生总数量': get_students_count}).inserted_id

# 查询动态属性值
grade = next( sheet[mc._id == gid].find() )
print(grade['学生总数量'])  # >>> 100
```

如果我们修改某个班级的学生数量,年级的【学生总数量】的返回值也会相应变化:

```python
next( sheet[mc._id == C1].find() ).update({'学生数量': 15})
print(grade['学生总数量'])  # >>> 105
```

### 讲解

1、使用 `@mpy.dynamic(...)` 装饰一个普通函数,该函数就会变成动态属性。

2、注意到这行代码 `def get_students_count(self: 'Row', id1, id2, id3, id4):` 中, `'Row'` 被加了引号 —— 当我们为动态属性的参数做类型提示时,必须以字符串的格式。以下这种方式是错误的: `def get_students_count(self: Row, id1, id2, id3, id4):` 。当然,类型提示只是用来让编辑器提示代码的,它可有可无,不是必要的。

3、可以在动态属性内导入并使用任何【标准库】和【第三方包】。

4、创建动态属性时,必须将所需要的参数值在 `@mpy.dynamic(...)` 的括号内传入。比如:我们定义的 `get_students_count` 需要 `id1, id2, id3, id4` 这四个参数,相对应地,我们在 `@mpy.dynamic(...)` 中传递了 `C1, C2, id3=C3, id4=C4` 这四个参数值。传递参数值时,既可以使用位置传参,也可以使用关键词传参,例如: `C1, C2` 使用了位置传参,而 `id3=C3, id4=C4` 使用了关键词传参。

5、动态属性是以人类易读的文本格式存储在 MongoDB 中的([查看图示](https://lcctoor.com/oodb/oa_/动态属性.png)),可直接通过 Navicat 等管理工具灵活修改。

## 面向对象特性综述

继承、方法、动态属性等特性都是动态解析的,当一个子对象继承一个父对象时,数据库中只会存储这两个对象的父子关系,而非把父对象的全部属性复制到子对象。因此:

1、当我们修改某个父对象的属性值时,仅该父对象的(在硬盘上的)实际存储值会发生变化,而它的子孙对象的(在硬盘上的)实际存储值不会发生任何变化,并且不会影响这两个对象的继承关系。

2、当我们欲修改任意一个对象的属性值时,除了使用 oodb(即本软件)的接口修改以外,也可以直接通过 Navicat 等管理工具手动修改,二者的效果是完全一致的。

## 条件筛选

### 示例一:理解条件筛选的基本范式

筛选【年龄>13,且视力≧4.6,且性别为女】的数据,并进行查改删:

**查询**:`sheet[mc.年龄 > 13][mc.视力 >= 4.6][mc.性别 == '女'].find( )`

**修改**:`sheet[mc.年龄 > 13][mc.视力 >= 4.6][mc.性别 == '女'].update( {'年级':'五年级', '爱好':'画画,跳绳'} )`

**删除**:`sheet[mc.年龄 > 13][mc.视力 >= 4.6][mc.性别 == '女'].delete( )`

### 筛选操作清单

| **代码**                                                                 | 解释                                            |
| ------------------------------------------------------------------------------ | ----------------------------------------------- |
| mc.年龄 > 10                                                                   | 大于                                            |
| mc.年龄 >= 10                                                                  | 大于或等于                                      |
| mc.年龄 < 10                                                                   | 小于                                            |
| mc.年龄 <= 10                                                                  | 小于或等于                                      |
| mc.年龄 == 10                                                                  | 等于                                            |
| mc.年龄 != 10                                                                  | 不等于                                          |
| mc.年级 == mf.isin( '初三', '高二' )                                           | 若字段值是传入值的成员,则符合                  |
| mc.年龄 == mf.notin( 10, 30, 45 )                                              | 若字段值不是传入值的成员,则符合                |
| mc.爱好 == mf.contain_all( '画画', '足球' )                                    | 若(列表)字段值包含传入值的所有元素,则符合    |
| mc.爱好 == mf.contain_any( '画画', '足球' )                                    | 若(列表)字段值包含传入值的至少1个元素,则符合 |
| mc.爱好 == mf.contain_none( '画画', '足球' )                                   | 若(列表)字段值不包含传入值的任何元素,则符合  |
| mc.姓名 == mf.re( '小' )                                                       | 正则匹配                                        |
| \[mc.年龄 > 3\][mc.年龄 < 100]                                                 | 交集(方式一)                                  |
| [ (mc.年龄 > 3) & (mc.年龄 < 100) ]                                            | 交集(方式二)                                  |
| [(mc.年龄<30)&#124; (mc.年龄>30) &#124; (mc.年龄==30) &#124; (mc.年龄==None)] | 并集                                            |
| [ (mc.年龄 > 3) - (mc.年龄 > 100) ]                                            | 差集                                            |
| [ ~(mc.年龄 > 100) ]                                                           | 补集                                            |

注:

1、isin、notin 用于判断(普通)字段的值是否传入值的成员,针对普通字段。

2、contain_any、contain_none 用于判断传入值是否(列表)字段的值的成员,针对列表字段。

3、isin、notin、contain_all、contain_any、contain_none 的传入值都不必是同类型的数据,以 isin 为例:可以这样使用:mc.tag == mf.isin( 3, 3.5, '学生', None ),传入值含有 int、float、str、NoneType 等多种类型。

4、成员运算符未传入任何值时的处理方式:

| **代码**                | **处理方式** |
| ----------------------------- | ------------------ |
| mc.年级 == mf.isin( )         | 所有数据都 不符合  |
| mc.年级 == mf.notin( )        | 所有数据都 符合    |
| mc.爱好 == mf.contain_all( )  | 所有数据都 符合    |
| mc.爱好 == mf.contain_any( )  | 所有数据都 不符合  |
| mc.爱好 == mf.contain_none( ) | 所有数据都 符合    |

5、四种集合运算可以相互嵌套,且可以无限嵌套。

### 示例二:理解并集、交集、补集的使用

筛选【年龄>13或视力≧4.6、且姓名含有‘小’、且年龄不高于15】的数据:

**查询**:`sheet[(mc.年龄>13) | (mc.视力>=4.6)][mc.姓名 == mf.re('小')][~(mc.年龄>15)].find( )`

**修改**:`sheet[(mc.年龄>13) | (mc.视力>=4.6)][mc.姓名 == mf.re('小')][~(mc.年龄>15)].update( {'年级':'初三'} )`

**删除**:`sheet[(mc.年龄>13) | (mc.视力>=4.6)][mc.姓名 == mf.re('小')][~(mc.年龄>15)].delete( )`

### 根据子元素过滤

可使用  mc.xxx.xxx.xxx...  的形式来表示子孙元素。

查询【语文成绩>80】的数据:

```python
sheet[mc.成绩.语文 > 80].find()
```

## 特殊字段名的表示方法

MongoDB 支持各种特殊的字段名,如:数字、符号、emoji 表情,这些字符在 Python 中不是合法变量名,因此使用  mc.1、mc.+  等格式会报错,可用  mc['1']、mc['+']、mc['👈']  这种格式代替。

## 字段提示

变量 mc 无字段提示功能,输入‘mc.’后,编辑器不会提示可选字段。

为了获得字段提示功能,可自建一个‘mc2’:

```python
class mc2(mc):
    姓名 = 年龄 = 幸运数字 = None
    class 成绩:
        语文 = 数学 = None

sheet[mc.姓名 == '小王'][mc2.年龄 > 10].find()
sheet[mc.姓名 == '小王'][mc2.成绩.语文 > 80].find()
```

注:

1、mc2 与 mc 用法完全一致,可混用。

2、mc2 设置字段提示后,仅具备提示效果,而不产生任何实际约束。

## 统计 与 删库删表

| 功能                   | 代码                        |
| ---------------------- | --------------------------- |
| 统计库的数量           | oom.len( )                  |
| 统计表的数量           | db.len( )                   |
| 统计行的数量           | sheet.len( )                |
| 统计符合条件的行的数量 | sheet[ mc.age > 8 ].len( ) |
| 获取库名清单           | oom.get_db_names( )         |
| 获取表名清单           | db.get_sheet_names( )       |
| 删除某个库             | db.delete_db( )             |
| 删除某张表             | sheet.delete_sheet( )       |

## 迭代所有 库OOM 和 表OOM

```python
for db in oom:
    for sheet in db:
        print(sheet.sheet_name)
```

## 特殊操作

### 示例:自增

由于新年到了,令所有学生的年龄增加 1 岁:

```python
sheet.update( {'年龄': mo.inc( 1 )} )
```

### 特殊操作清单:

| **语法**        | **含义**                                     |
| --------------------- | -------------------------------------------------- |
| mo.inc( 1.5 )         | 自增 1.5                                           |
| mo.inc( -1.5 )        | 自减 1.5                                           |
| mo.add( 1, 2, 3 )     | 向列表字段添加元素,仅当被添加的元素不存在时才添加 |
| mo.push( 1, 2, 3 )    | 向列表字段添加元素,无论被添加的元素是否存在都添加 |
| mo.pull( 15 )         | 从列表字段删除 1 个等于 15 的值                    |
| mo.popfirst           | 从列表字段删除第 1 个元素                          |
| mo.poplast            | 从列表字段删除最后 1 个元素                        |
| mo.rename( '新名称' ) | 重命名字段                                         |
| mo.unset              | 删除字段                                           |
| mo.delete             | 删除字段(与 mo.unset 等价)                       |

示例:

```python
sheet[mc.姓名=='小六'].update({
    '姓名': 'xiaoliu',          # 修改为‘xiaoliu’
    '年龄': mo.inc(6),          # 自增6
    '幸运数字': mo.push(666),   # 添加666
    '视力': mo.rename('眼力'),  # 字段名改为‘眼力’
    '籍贯': mo.delete,          # 删除此字段
    '成绩.语文': 60,            # 改为60分
    '成绩.数学': mo.inc(-6)     # 减6分
})
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "oodb",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "OODBMS, OODBS, oodb",
    "author": null,
    "author_email": "\u6c5f\u5357\u96e8\u4e0a <lcctoor@outlook.com>",
    "download_url": "https://files.pythonhosted.org/packages/b5/ef/1aba0827a1bffdc2c16b0b0447eb994c695335f6db91160a26934da3e0e5/oodb-1.0.3.tar.gz",
    "platform": null,
    "description": "# \u9879\u76ee\u63cf\u8ff0\n\n\u9762\u5411\u5bf9\u8c61\u6570\u636e\u5e93 \u2014\u2014 \u5f15\u5165\u4e86 Python \u4e2d\u7c7b\u7684\u7279\u6027\uff0c\u5982\uff1a\u7ee7\u627f\u3001\u91cd\u5199\u3001\u65b9\u6cd5\u3001\u52a8\u6001\u5c5e\u6027\u7b49\u3002\n\n\u8be5\u8f6f\u4ef6\u4f7f\u7528 MongoDB \u6765\u6301\u4e45\u5316\u6570\u636e\uff0c\u5e76\u5728 Python \u5c42\u9762\u5229\u7528\u8f6f\u4ef6\u7b97\u6cd5\u6a21\u62df\u51fa\u7ee7\u627f\u7b49\u7279\u6027\u3002\n\n\u5982\u679c\u4f60\u4e0d\u9700\u8981\u4f7f\u7528\u7ee7\u627f\u3001\u91cd\u5199\u7b49\u7279\u6027\uff0c\u800c\u53ea\u662f\u9700\u8981\u4e00\u4e2a\u7528\u6765\u64cd\u4f5c MongoDB \u7684 ODM\uff0c\u6211\u4eec\u4e3a\u4f60\u51c6\u5907\u4e86\u53e6\u4e00\u6b3e\u66f4\u5408\u9002\u7684\u5de5\u5177 \u2014\u2014 [oomongo](https://pypi.org/project/oomongo/) \u3002\n\n# \u4f5c\u8005\n\n\u6c5f\u5357\u96e8\u4e0a\n\n[\u4e3b\u9875](https://lcctoor.com/index.html) \\| [Github](https://github.com/lcctoor) \\| [PyPi](https://pypi.org/user/lcctoor) \\| [\u5fae\u4fe1](https://lcctoor.com/cdn/WeChatQRC.jpg) \\| [\u90ae\u7bb1](mailto:lcctoor@outlook.com) \\| [\u6350\u8d60](https://lcctoor.com/cdn/DonationQRC-0rmb.jpg)\n\n# Bug\u63d0\u4ea4\u3001\u529f\u80fd\u63d0\u8bae\n\n\u4f60\u53ef\u4ee5\u901a\u8fc7 [Github-Issues](https://github.com/lcctoor/arts/issues)\u3001[\u5fae\u4fe1](https://lcctoor.com/cdn/WeChatQRC.jpg) \u4e0e\u6211\u8054\u7cfb\u3002\n\n# \u5b89\u88c5\n\n```\npip install oodb\n```\n\n# \u6559\u7a0b\n\n\u672c\u6587\u5c06\u4ee5\u7b80\u6d01\u7684\u65b9\u5f0f\u5411\u4f60\u4ecb\u7ecd\u6838\u5fc3\u77e5\u8bc6\uff0c\u800c\u4e0d\u4f1a\u8ba9\u4f60\u88ab\u7e41\u7410\u7684\u672f\u8bed\u6240\u6df9\u6ca1\u3002\n\n## \u5bfc\u5165\n\n```python\nfrom pymongo import MongoClient\nfrom oodb import OOM, Row, mc, mf, mo, mpy\n```\n\n## \u521b\u5efaOOM\n\n```python\nclass OOM_2(OOM):\n    def mkconn(self):\n        return MongoClient(host='localhost', port=27017)  # MongoDB \u8fde\u63a5\u5668\uff0c\u7528\u6765\u5199\u5165\u548c\u8bfb\u53d6\u6570\u636e\n\noom = OOM_2()          # \u8d26\u6237OOM\ndb = oom['\u6cc9\u5dde\u5e02']      # \u5e93OOM\nsheet = db['\u5e0c\u671b\u5c0f\u5b66']  # \u8868OOM\n```\n\n## \u57fa\u7840\u529f\u80fd \u2014\u2014 \u589e\u3001\u5220\u3001\u6539\u3001\u67e5\n\n\u3010\u589e\u3001\u5220\u3001\u6539\u3001\u67e5\u3011\u7684\u65b9\u6cd5\u540d\u79f0\u5206\u522b\u4e3a\uff1ainsert\u3001delete\u3001update\u3001find \u3002\n\n### \u793a\u4f8b\n\n```python\nrow1 = {'\u59d3\u540d':'\u5c0f\u4e00', '\u5e74\u9f84':11, '\u5e78\u8fd0\u6570\u5b57':[1, 2, 3], '\u6210\u7ee9':{'\u8bed\u6587':81, '\u6570\u5b66':82}}\nrow2 = {'\u59d3\u540d':'\u5c0f\u4e8c', '\u5e74\u9f84':12, '\u5e78\u8fd0\u6570\u5b57':[2, 3, 4], '\u6210\u7ee9':{'\u8bed\u6587':82, '\u6570\u5b66':83}}\nrow3 = {'\u59d3\u540d':'\u5c0f\u4e09', '\u5e74\u9f84':13, '\u5e78\u8fd0\u6570\u5b57':[3, 4, 5], '\u6210\u7ee9':{'\u8bed\u6587':83, '\u6570\u5b66':84}}\nrow4 = {'\u59d3\u540d':'\u5c0f\u56db', '\u5e74\u9f84':14, '\u5e78\u8fd0\u6570\u5b57':[4, 5, 6], '\u6210\u7ee9':{'\u8bed\u6587':84, '\u6570\u5b66':85}}\nrow5 = {'\u59d3\u540d':'\u5c0f\u4e94', '\u5e74\u9f84':15, '\u5e78\u8fd0\u6570\u5b57':[5, 6, 7], '\u6210\u7ee9':{'\u8bed\u6587':85, '\u6570\u5b66':86}}\nrow6 = {'\u59d3\u540d':'\u5c0f\u516d', '\u5e74\u9f84':16, '\u5e78\u8fd0\u6570\u5b57':[6, 7, 8], '\u6210\u7ee9':{'\u8bed\u6587':86, '\u6570\u5b66':87}}\n```\n\n|    \u529f\u80fd    | \u4ee3\u7801                                                            |                               \u5907\u6ce8                               |\n| :---------: | --------------------------------------------------------------- | :--------------------------------------------------------------: |\n| \u589e\uff081\u00a0\u6761\uff09 | sheet.insert( row1 )                                            |                                /                                |\n| \u589e\uff08\u6279\u91cf\uff09 | sheet.insert( row2, row3 )                                      |                                /                                |\n|     \u5220     | sheet.delete( )                                                 |                                /                                |\n|     \u6539     | sheet.update( {'\u5e74\u9f84': 100} )                                   |                                /                                |\n|     \u67e5     | for  row  in \u00a0sheet.find( ):<br />\u00a0 \u00a0 \u00a0print( row['\u59d3\u540d'] ) | find \u65b9\u6cd5\u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u56e0\u6b64\u9700\u8981\u4f7f\u7528 for \u5faa\u73af\u83b7\u53d6\u00a0row \u5bf9\u8c61 |\n\n\u5220\u9664\u3001\u4fee\u6539\u3001\u67e5\u8be2\u65f6\uff0c\u53ef\u4f20\u9012 limit \u53c2\u6570\u6765\u9650\u5236\u884c\u6570\uff1a\n\n| \u529f\u80fd | \u4ee3\u7801                                                                     |\n| :--: | ------------------------------------------------------------------------ |\n|  \u5220  | sheet.delete( limit=10 )                                                 |\n|  \u6539  | sheet.update( {'\u5e74\u9f84': 100},\u00a0limit=10 )                                 |\n|  \u67e5  | for  row  in \u00a0sheet.find( limit=10 ):<br />\u00a0 \u00a0 \u00a0print( row['\u59d3\u540d'] ) |\n\n### \u65b0\u589e\u65f6\uff0c\u67e5\u770b\u5206\u914d\u5230\u7684\u4e3b\u952e\uff1a\n\n```python\nrow1 = {'\u59d3\u540d':'\u5c0f\u4e00', '\u5e74\u9f84':11, '\u5e78\u8fd0\u6570\u5b57':[1, 2, 3], '\u6210\u7ee9':{'\u8bed\u6587':81, '\u6570\u5b66':82}}\nrow2 = {'\u59d3\u540d':'\u5c0f\u4e8c', '\u5e74\u9f84':12, '\u5e78\u8fd0\u6570\u5b57':[2, 3, 4], '\u6210\u7ee9':{'\u8bed\u6587':82, '\u6570\u5b66':83}}\nrow3 = {'\u59d3\u540d':'\u5c0f\u4e09', '\u5e74\u9f84':13, '\u5e78\u8fd0\u6570\u5b57':[3, 4, 5], '\u6210\u7ee9':{'\u8bed\u6587':83, '\u6570\u5b66':84}}\n\nr1 = sheet.insert( row1 )\nr2 = sheet.insert( row2, row3 )\n```\n\n\u65b9\u6cd51\uff1a\u4f7f\u7528 insert \u6dfb\u52a0\u6570\u636e\u6210\u529f\u540e\uff0crow1~row3 \u5df2\u5404\u81ea\u591a\u4e86\u4e00\u4e2a\u53eb\u2018_id\u2019\u7684\u952e\uff0c\u8be5\u952e\u7684\u503c\u5373\u5206\u914d\u5230\u7684\u4e3b\u952e\u3002\n\n\u65b9\u6cd52\uff1a\n\n```python\nr1.inserted_id\nr2.inserted_ids\n```\n\n## \u7ee7\u627f\n\n\u8ba9\u6211\u4eec\u4ee5 iPhone15 \u4e3a\u4f8b\u5b50\u6765\u8bb2\u89e3\u3010\u7ee7\u627f\u3011\u3002\n\n### \u65b0\u589e\u4e00\u4e2a\u3010128G-\u9ed1\u8272\u3011\u7248\u672c\u7684\u5bf9\u8c61\n\n\u6211\u4eec\u53d1\u73b0\uff0ciPhone15 \u7684\u4e0d\u540c\u7248\u672c\u662f\u7531\u3010\u6027\u80fd\u3011\u548c\u3010\u5916\u89c2\u3011\u8fd9\u4e24\u4e2a\u7ef4\u5ea6\u7ec4\u5408\u800c\u6210\u7684\u3002\u56e0\u6b64\uff0c\u5047\u5982\u6211\u4eec\u8981\u65b0\u589e\u4e00\u4e2a\u3010128G-\u9ed1\u8272\u3011\u7248\u672c\u7684\u5bf9\u8c61\uff0c\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u505a\uff1a\n\n1\u3001\u521b\u5efa \u57fa\u7840\u6570\u636e\u3001128G\u6027\u80fd\u6570\u636e\u3001\u9ed1\u8272\u5916\u89c2\u6570\u636e \u4e09\u6761\u6570\u636e\uff1a\n\n```python\ninfo_base = {'\u64cd\u4f5c\u7cfb\u7edf': 'iOS', 'CPU\u578b\u53f7': 'A16', '\u5c4f\u5e55\u5c3a\u5bf8': '6.1\u82f1\u5bf8'}\ninfo_128G = {'\u5185\u5b58': '128G', '\u4ef7\u683c': 4849}\ninfo_\u9ed1 = {'\u8fb9\u6846\u989c\u8272': '\u9ed1', '\u540e\u76d6\u989c\u8272': '\u9ed1'}\n```\n\n2\u3001\u628a\u8fd9\u4e09\u6761\u6570\u636e\u63d2\u5165\u5230\u6570\u636e\u5e93\uff0c\u5e76\u83b7\u53d6\u5bf9\u5e94\u7684 _id \u503c\uff1a\n\n```python\n[id_base, id_128G, id_\u9ed1] = sheet.insert( info_base, info_128G, info_\u9ed1 ).inserted_ids\n```\n\n3\u3001\u521b\u5efa\u3010128G-\u9ed1\u8272\u3011\u7248\u672c\u6570\u636e\uff0c\u63d2\u5165\u5230\u6570\u636e\u5e93\uff0c\u5e76\u83b7\u53d6\u5bf9\u5e94\u7684 _id \u503c\uff1a\n\n```python\nid_128G_\u9ed1 = sheet.insert({'\u7248\u672c\u540d\u79f0': '128G-\u9ed1\u8272'}, bases=[id_base, id_128G, id_\u9ed1]).inserted_id\n```\n\n\u67e5\u8be2\u3010128G-\u9ed1\u8272\u3011\u7248\u672c\u5bf9\u8c61\u7684\u4fe1\u606f\uff1a\n\n```python\nrow_128G_\u9ed1 = next( sheet[mc.\u7248\u672c\u540d\u79f0 == '128G-\u9ed1\u8272'].find() )\n\nfor key in ('\u7248\u672c\u540d\u79f0', '\u64cd\u4f5c\u7cfb\u7edf', '\u5185\u5b58', '\u8fb9\u6846\u989c\u8272'):  # row_128G_\u9ed1 \u7ee7\u627f\u4e86 row_base, row_128G, row_\u9ed1, \u56e0\u6b64\u5177\u6709\u5b83\u4eec\u7684\u5c5e\u6027\u53ca\u5176\u503c\n    print(row_128G_\u9ed1[key])\n\n# >>> 128G-\u9ed1\u8272\n# >>> iOS\n# >>> 128G\n# >>> \u9ed1\n```\n\n### \u65b0\u589e\u4e00\u4e2a\u3010128G-\u767d\u8272\u3011\u7248\u672c\u7684\u5bf9\u8c61\n\n```python\n# \u521b\u5efa\u3010\u767d\u8272\u5916\u89c2\u3011\u6570\u636e\uff0c\u63d2\u5165\u5230\u6570\u636e\u5e93\uff0c\u5e76\u83b7\u53d6\u5bf9\u5e94\u7684 _id \u503c\uff1a\nid_\u767d = sheet.insert({'\u8fb9\u6846\u989c\u8272': '\u767d', '\u540e\u76d6\u989c\u8272': '\u767d'}).inserted_id\n\n# \u521b\u5efa\u3010128G-\u767d\u8272\u3011\u7248\u672c\u6570\u636e\uff0c\u63d2\u5165\u5230\u6570\u636e\u5e93\uff0c\u5e76\u83b7\u53d6\u5bf9\u5e94\u7684 _id \u503c\uff1a\nid_128G_\u767d = sheet.insert({'\u7248\u672c\u540d\u79f0': '128G-\u767d\u8272'}, bases=[id_\u767d, id_128G_\u9ed1]).inserted_id\n```\n\n\u67e5\u8be2\u3010128G-\u767d\u8272\u3011\u7248\u672c\u5bf9\u8c61\u7684\u4fe1\u606f\uff1a\n\n```python\nrow_128G_\u767d = next( sheet[mc.\u7248\u672c\u540d\u79f0 == '128G-\u767d\u8272'].find() )\n\nfor key in ('\u7248\u672c\u540d\u79f0', '\u64cd\u4f5c\u7cfb\u7edf', '\u5185\u5b58', '\u8fb9\u6846\u989c\u8272'):\n    print(row_128G_\u767d[key])\n\n# >>> 128G-\u767d\u8272\n# >>> iOS\n# >>> 128G\n# >>> \u767d\n```\n\n### \u5c5e\u6027\u67e5\u627e\u987a\u5e8f\n\n\u5728\u4ee5\u4e0a\u793a\u4f8b\u4e2d\uff0c\u5f53\u6211\u4eec\u65b0\u589e\u3010128G-\u767d\u8272\u3011\u7248\u672c\u5bf9\u8c61\u65f6\uff0c\u7ee7\u627f\u4e86 `row_\u767d` \u548c `row_128G_\u9ed1` \uff0c\u8fd9\u4e24\u4e2a\u7236\u5bf9\u8c61\u90fd\u5177\u6709 `\u8fb9\u6846\u989c\u8272` \u5c5e\u6027\uff0c\u524d\u8005\u7684\u8be5\u5c5e\u6027\u503c\u4e3a\u201c\u767d\u201d\uff0c\u540e\u8005\u7684\u8be5\u5c5e\u6027\u503c\u4e3a\u201c\u9ed1\u201d\u3002\u6700\u540e\uff0c\u5f53\u6211\u4eec\u6253\u5370 `row_128G_\u767d` \u5bf9\u8c61\u7684 `\u8fb9\u6846\u989c\u8272` \u5c5e\u6027\u65f6\uff0c\u6253\u5370\u51fa\u6765\u7684\u7ed3\u679c\u4e3a `\u767d` \u3002\n\n\u5f53\u4e00\u4e2a\u5bf9\u8c61\u7ee7\u627f\u81ea\u591a\u4e2a\u7236\u5bf9\u8c61\uff0c\u5e76\u4e14\u5bf9\u4e8e\u67d0\u4e00\u5c5e\u6027\uff0c\u8fd9\u4e9b\u7236\u5bf9\u8c61\u7684\u8be5\u5c5e\u6027\u503c\u5404\u4e0d\u76f8\u540c\u65f6\uff0c\u5b50\u5bf9\u8c61\u5728\u8868\u73b0\u8be5\u5c5e\u6027\u503c\u65f6\uff0c\u4f1a\u9075\u5faa\u3010C3\u7ebf\u6027\u5316\u7b97\u6cd5\u3011\uff1a\n\n1\u3001\u9996\u5148\uff0c\u5b50\u5bf9\u8c61\u4f1a\u5728\u81ea\u8eab\u7684\u5c5e\u6027\u4e2d\u67e5\u627e\u8be5\u5c5e\u6027\uff0c\u5982\u679c\u627e\u5230\u4e86\uff0c\u5219\u7acb\u5373\u8fd4\u56de\u8be5\u5c5e\u6027\u503c\u3002\n\n2\u3001\u5982\u679c\u5728\u81ea\u8eab\u7684\u5c5e\u6027\u4e2d\u627e\u4e0d\u5230\u8be5\u5c5e\u6027\uff0c\u5219\u4f1a\u6309\u7167\u4ece\u5de6\u5f80\u53f3\u7684\u987a\u5e8f\uff0c\u5148\u4ece\u5de6\u8fb9\u7b2c 1 \u4e2a\u7236\u5bf9\u8c61\u4e2d\u67e5\u627e\uff0c\u5982\u679c\u67e5\u627e\u4e0d\u5230\u5219\u518d\u4ece\u7b2c 2 \u4e2a\u7236\u5bf9\u8c61\u4e2d\u67e5\u627e\u2026\u2026\u76f4\u5230\u5728\u67d0\u4e2a\u7236\u5bf9\u8c61\u4e2d\u627e\u5230\u8be5\u5c5e\u6027\u65f6\uff0c\u5219\u7acb\u5373\u8fd4\u56de\u5c5e\u6027\u503c\u3002\n\n## \u91cd\u5199\n\n\u5047\u5982\u82f9\u679c\u516c\u53f8\u4e0e\u4e2d\u56fd\u8054\u901a\u516c\u53f8\u5408\u4f5c\uff0c\u63a8\u51fa\u4e86\u3010128G-\u767d\u8272-\u8054\u901a\u5408\u4f5c\u3011\u7248\u672c\u7684 iPhone15 \uff0c\u5176\u5404\u65b9\u9762\u53c2\u6570\u4e0e\u3010128G-\u767d\u8272\u3011\u7248\u672c\u552f\u4e00\u7684\u533a\u522b\u5c31\u662f\u7248\u672c\u540d\u79f0\u6539\u6210\u4e86\u201c128G-\u767d\u8272-\u8054\u901a\u5408\u4f5c\u201d\uff0c\u6b64\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528\u3010\u91cd\u5199\u3011\u7684\u7279\u6027\u65b9\u4fbf\u5730\u65b0\u589e\u4e00\u4e2a\u3010128G-\u767d\u8272-\u8054\u901a\u5408\u4f5c\u3011\u7248\u672c\u7684\u5bf9\u8c61\uff1a\n\n```python\nid_128G_\u767d_\u8054\u901a\u5408\u4f5c = sheet.insert({'\u7248\u672c\u540d\u79f0': '128G-\u767d\u8272-\u8054\u901a\u5408\u4f5c'}, bases=[id_128G_\u767d]).inserted_id\n```\n\n\u5728\u6b64\u4f8b\u4e2d\uff0c\u6211\u4eec\u5728\u65b0\u589e `row_128G_\u767d_\u8054\u901a\u5408\u4f5c` \u5bf9\u8c61\u65f6\uff0c\u7ee7\u627f\u4e86 `row_128G_\u767d` \u5bf9\u8c61\uff0c\u5e76\u91cd\u5199\u4e86 `\u7248\u672c\u540d\u79f0` \u5c5e\u6027\u3002\n\n## \u65b9\u6cd5\n\n\u8ba9\u6211\u4eec\u5b9a\u4e49\u4e00\u4e2a\u65b9\u6cd5\uff1a\u8be5\u65b9\u6cd5\u63a5\u6536\u4e00\u4e2a `name` \u53c2\u6570\uff0c\u7136\u540e\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32 \u2014\u2014 `[<\u5f53\u524d\u65f6\u95f4>] \u4f60\u597d\uff0c<name>\uff01\u6211\u662f\u3010<\u7248\u672c\u540d\u79f0>\u3011\u7248\u672c\u7684 iPhone15\uff0c\u5f88\u9ad8\u5174\u6210\u4e3a\u4f60\u7684\u79fb\u52a8\u52a9\u7406\uff01` \u3002\n\n```python\n# \u521b\u5efa\u5bf9\u8c61\u65b9\u6cd5\n@mpy.method\ndef say_hello(self: 'Row', name: 'str'):\n    import time\n    \u7248\u672c\u540d\u79f0 = self['\u7248\u672c\u540d\u79f0']\n    return f\"[{int(time.time())}] \u4f60\u597d\uff0c{name}\uff01\u6211\u662f\u3010{\u7248\u672c\u540d\u79f0}\u3011\u7248\u672c\u7684 iPhone15\uff0c\u5f88\u9ad8\u5174\u6210\u4e3a\u4f60\u7684\u79fb\u52a8\u52a9\u7406\uff01\"\n\n# \u5c06\u5bf9\u8c61\u65b9\u6cd5\u8d4b\u503c\u7ed9\u57fa\u5bf9\u8c61base, \u5b83\u7684\u5b50\u5b59\u5bf9\u8c61\u90fd\u5c06\u7ee7\u627f\u6b64\u65b9\u6cd5\nbase_obj = next( sheet[mc._id == id_base].find() )\nbase_obj.update({'say_hello': say_hello})\n\n# \u8c03\u7528\u5bf9\u8c61\u65b9\u6cd5\nfor _id in [id_128G_\u9ed1, id_128G_\u767d, id_128G_\u767d_\u8054\u901a\u5408\u4f5c]:\n    obj = next( sheet[mc._id == _id].find() )\n    say_hello = obj['say_hello']\n    print(say_hello('\u7a0b\u5e8f\u733f'))\n\n# >>> [1709654174] \u4f60\u597d\uff0c\u7a0b\u5e8f\u733f\uff01\u6211\u662f\u3010128G-\u9ed1\u8272\u3011\u7248\u672c\u7684 iPhone15\uff0c\u5f88\u9ad8\u5174\u6210\u4e3a\u4f60\u7684\u79fb\u52a8\u52a9\u7406\uff01\n# >>> [1709654174] \u4f60\u597d\uff0c\u7a0b\u5e8f\u733f\uff01\u6211\u662f\u3010128G-\u767d\u8272\u3011\u7248\u672c\u7684 iPhone15\uff0c\u5f88\u9ad8\u5174\u6210\u4e3a\u4f60\u7684\u79fb\u52a8\u52a9\u7406\uff01\n# >>> [1709654174] \u4f60\u597d\uff0c\u7a0b\u5e8f\u733f\uff01\u6211\u662f\u3010128G-\u767d\u8272-\u8054\u901a\u5408\u4f5c\u3011\u7248\u672c\u7684 iPhone15\uff0c\u5f88\u9ad8\u5174\u6210\u4e3a\u4f60\u7684\u79fb\u52a8\u52a9\u7406\uff01\n```\n\n### \u8bb2\u89e3\n\n1\u3001\u4f7f\u7528 `@mpy.method` \u88c5\u9970\u4e00\u4e2a\u666e\u901a\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5c31\u4f1a\u53d8\u6210\u5bf9\u8c61\u65b9\u6cd5\u3002\n\n2\u3001\u6ce8\u610f\u5230\u8fd9\u884c\u4ee3\u7801 `def say_hello(self: 'Row', name: 'str'):` \u4e2d\uff0c `'Row'` \u548c `'str'` \u88ab\u52a0\u4e86\u5f15\u53f7 \u2014\u2014 \u5f53\u6211\u4eec\u4e3a\u5bf9\u8c61\u65b9\u6cd5\u7684\u53c2\u6570\u505a\u7c7b\u578b\u63d0\u793a\u65f6\uff0c\u5fc5\u987b\u4ee5\u5b57\u7b26\u4e32\u7684\u683c\u5f0f\u3002\u4ee5\u4e0b\u8fd9\u79cd\u65b9\u5f0f\u662f\u9519\u8bef\u7684\uff1a `def say_hello(self: Row, name: str):` \u3002\u5f53\u7136\uff0c\u7c7b\u578b\u63d0\u793a\u53ea\u662f\u7528\u6765\u8ba9\u7f16\u8f91\u5668\u63d0\u793a\u4ee3\u7801\u7684\uff0c\u5b83\u53ef\u6709\u53ef\u65e0\uff0c\u4e0d\u662f\u5fc5\u8981\u7684\u3002\n\n3\u3001\u53ef\u4ee5\u5728\u5bf9\u8c61\u65b9\u6cd5\u5185\u5bfc\u5165\u5e76\u4f7f\u7528\u4efb\u4f55\u3010\u6807\u51c6\u5e93\u3011\u548c\u3010\u7b2c\u4e09\u65b9\u5305\u3011\u3002\n\n4\u3001\u8c03\u7528\u5bf9\u8c61\u65b9\u6cd5\u65f6\uff0c\u65e2\u53ef\u4ee5\u4f7f\u7528\u4f4d\u7f6e\u4f20\u53c2\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u8bcd\u4f20\u53c2\u3002\u4f8b\u5982\uff0c\u8fd9\u4e24\u79cd\u65b9\u5f0f\u90fd\u662f\u53ef\u884c\u7684\uff1a `say_hello('\u7a0b\u5e8f\u733f')` \u3001 `say_hello(name='\u7a0b\u5e8f\u733f')` \u3002\n\n5\u3001\u5bf9\u8c61\u65b9\u6cd5\u662f\u4ee5\u4eba\u7c7b\u6613\u8bfb\u7684\u6587\u672c\u683c\u5f0f\u5b58\u50a8\u5728 MongoDB \u4e2d\u7684\uff08[\u67e5\u770b\u56fe\u793a](https://lcctoor.com/oodb/oa_/\u5bf9\u8c61\u65b9\u6cd5.png)\uff09\uff0c\u53ef\u76f4\u63a5\u901a\u8fc7 Navicat \u7b49\u7ba1\u7406\u5de5\u5177\u7075\u6d3b\u4fee\u6539\u3002\n\n## \u52a8\u6001\u5c5e\u6027\n\n\u8ba9\u6211\u4eec\u7528\u4e00\u4e2a\u7edf\u8ba1\u5b66\u751f\u603b\u6570\u7684\u6848\u4f8b\u6765\u8bb2\u89e3\u3010\u52a8\u6001\u5c5e\u6027\u3011\u3002\n\n```python\n# \u65b0\u589e\u56db\u4e2a\u73ed\u7ea7\u5bf9\u8c61\nC1 = sheet.insert({'\u73ed\u7ea7\u7f16\u53f7': 1, '\u5b66\u751f\u6570\u91cf': 10}).inserted_id\nC2 = sheet.insert({'\u73ed\u7ea7\u7f16\u53f7': 2, '\u5b66\u751f\u6570\u91cf': 20}).inserted_id\nC3 = sheet.insert({'\u73ed\u7ea7\u7f16\u53f7': 3, '\u5b66\u751f\u6570\u91cf': 30}).inserted_id\nC4 = sheet.insert({'\u73ed\u7ea7\u7f16\u53f7': 4, '\u5b66\u751f\u6570\u91cf': 40}).inserted_id\n\n# \u521b\u5efa\u4e00\u4e2a\u83b7\u53d6\u5b66\u751f\u603b\u6570\u91cf\u7684\u52a8\u6001\u5c5e\u6027\u503c\n@mpy.dynamic(C1, C2, id3=C3, id4=C4)\ndef get_students_count(self: 'Row', id1, id2, id3, id4):\n    from oodb import Row  # Row \u5728\u5b9e\u4f8b\u5316\u65f6\u9700\u8981\u63a5\u6536\u4e24\u4e2a\u53c2\u6570: (parent: Sheet, _id)\n    rows = [Row(parent=self.parent, _id=x) for x in (id1, id2, id3, id4)]\n    return sum( [x['\u5b66\u751f\u6570\u91cf'] for x in rows] )\n\n# \u65b0\u589e\u4e00\u4e2a\u5e74\u7ea7\u5bf9\u8c61\uff0c\u5e76\u5c06\u3010\u52a8\u6001\u5c5e\u6027\u503c\u3011\u8d4b\u503c\u7ed9\u3010\u5b66\u751f\u603b\u6570\u91cf\u3011\u5c5e\u6027\ngid = sheet.insert({'\u5e74\u7ea7': '\u4e94\u5e74\u7ea7', '\u5b66\u751f\u603b\u6570\u91cf': get_students_count}).inserted_id\n\n# \u67e5\u8be2\u52a8\u6001\u5c5e\u6027\u503c\ngrade = next( sheet[mc._id == gid].find() )\nprint(grade['\u5b66\u751f\u603b\u6570\u91cf'])  # >>> 100\n```\n\n\u5982\u679c\u6211\u4eec\u4fee\u6539\u67d0\u4e2a\u73ed\u7ea7\u7684\u5b66\u751f\u6570\u91cf\uff0c\u5e74\u7ea7\u7684\u3010\u5b66\u751f\u603b\u6570\u91cf\u3011\u7684\u8fd4\u56de\u503c\u4e5f\u4f1a\u76f8\u5e94\u53d8\u5316\uff1a\n\n```python\nnext( sheet[mc._id == C1].find() ).update({'\u5b66\u751f\u6570\u91cf': 15})\nprint(grade['\u5b66\u751f\u603b\u6570\u91cf'])  # >>> 105\n```\n\n### \u8bb2\u89e3\n\n1\u3001\u4f7f\u7528 `@mpy.dynamic(...)` \u88c5\u9970\u4e00\u4e2a\u666e\u901a\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5c31\u4f1a\u53d8\u6210\u52a8\u6001\u5c5e\u6027\u3002\n\n2\u3001\u6ce8\u610f\u5230\u8fd9\u884c\u4ee3\u7801 `def get_students_count(self: 'Row', id1, id2, id3, id4):` \u4e2d\uff0c `'Row'` \u88ab\u52a0\u4e86\u5f15\u53f7 \u2014\u2014 \u5f53\u6211\u4eec\u4e3a\u52a8\u6001\u5c5e\u6027\u7684\u53c2\u6570\u505a\u7c7b\u578b\u63d0\u793a\u65f6\uff0c\u5fc5\u987b\u4ee5\u5b57\u7b26\u4e32\u7684\u683c\u5f0f\u3002\u4ee5\u4e0b\u8fd9\u79cd\u65b9\u5f0f\u662f\u9519\u8bef\u7684\uff1a `def get_students_count(self: Row, id1, id2, id3, id4):` \u3002\u5f53\u7136\uff0c\u7c7b\u578b\u63d0\u793a\u53ea\u662f\u7528\u6765\u8ba9\u7f16\u8f91\u5668\u63d0\u793a\u4ee3\u7801\u7684\uff0c\u5b83\u53ef\u6709\u53ef\u65e0\uff0c\u4e0d\u662f\u5fc5\u8981\u7684\u3002\n\n3\u3001\u53ef\u4ee5\u5728\u52a8\u6001\u5c5e\u6027\u5185\u5bfc\u5165\u5e76\u4f7f\u7528\u4efb\u4f55\u3010\u6807\u51c6\u5e93\u3011\u548c\u3010\u7b2c\u4e09\u65b9\u5305\u3011\u3002\n\n4\u3001\u521b\u5efa\u52a8\u6001\u5c5e\u6027\u65f6\uff0c\u5fc5\u987b\u5c06\u6240\u9700\u8981\u7684\u53c2\u6570\u503c\u5728 `@mpy.dynamic(...)` \u7684\u62ec\u53f7\u5185\u4f20\u5165\u3002\u6bd4\u5982\uff1a\u6211\u4eec\u5b9a\u4e49\u7684 `get_students_count` \u9700\u8981 `id1, id2, id3, id4` \u8fd9\u56db\u4e2a\u53c2\u6570\uff0c\u76f8\u5bf9\u5e94\u5730\uff0c\u6211\u4eec\u5728 `@mpy.dynamic(...)` \u4e2d\u4f20\u9012\u4e86 `C1, C2, id3=C3, id4=C4` \u8fd9\u56db\u4e2a\u53c2\u6570\u503c\u3002\u4f20\u9012\u53c2\u6570\u503c\u65f6\uff0c\u65e2\u53ef\u4ee5\u4f7f\u7528\u4f4d\u7f6e\u4f20\u53c2\uff0c\u4e5f\u53ef\u4ee5\u4f7f\u7528\u5173\u952e\u8bcd\u4f20\u53c2\uff0c\u4f8b\u5982\uff1a `C1, C2` \u4f7f\u7528\u4e86\u4f4d\u7f6e\u4f20\u53c2\uff0c\u800c `id3=C3, id4=C4` \u4f7f\u7528\u4e86\u5173\u952e\u8bcd\u4f20\u53c2\u3002\n\n5\u3001\u52a8\u6001\u5c5e\u6027\u662f\u4ee5\u4eba\u7c7b\u6613\u8bfb\u7684\u6587\u672c\u683c\u5f0f\u5b58\u50a8\u5728 MongoDB \u4e2d\u7684\uff08[\u67e5\u770b\u56fe\u793a](https://lcctoor.com/oodb/oa_/\u52a8\u6001\u5c5e\u6027.png)\uff09\uff0c\u53ef\u76f4\u63a5\u901a\u8fc7 Navicat \u7b49\u7ba1\u7406\u5de5\u5177\u7075\u6d3b\u4fee\u6539\u3002\n\n## \u9762\u5411\u5bf9\u8c61\u7279\u6027\u7efc\u8ff0\n\n\u7ee7\u627f\u3001\u65b9\u6cd5\u3001\u52a8\u6001\u5c5e\u6027\u7b49\u7279\u6027\u90fd\u662f\u52a8\u6001\u89e3\u6790\u7684\uff0c\u5f53\u4e00\u4e2a\u5b50\u5bf9\u8c61\u7ee7\u627f\u4e00\u4e2a\u7236\u5bf9\u8c61\u65f6\uff0c\u6570\u636e\u5e93\u4e2d\u53ea\u4f1a\u5b58\u50a8\u8fd9\u4e24\u4e2a\u5bf9\u8c61\u7684\u7236\u5b50\u5173\u7cfb\uff0c\u800c\u975e\u628a\u7236\u5bf9\u8c61\u7684\u5168\u90e8\u5c5e\u6027\u590d\u5236\u5230\u5b50\u5bf9\u8c61\u3002\u56e0\u6b64\uff1a\n\n1\u3001\u5f53\u6211\u4eec\u4fee\u6539\u67d0\u4e2a\u7236\u5bf9\u8c61\u7684\u5c5e\u6027\u503c\u65f6\uff0c\u4ec5\u8be5\u7236\u5bf9\u8c61\u7684\uff08\u5728\u786c\u76d8\u4e0a\u7684\uff09\u5b9e\u9645\u5b58\u50a8\u503c\u4f1a\u53d1\u751f\u53d8\u5316\uff0c\u800c\u5b83\u7684\u5b50\u5b59\u5bf9\u8c61\u7684\uff08\u5728\u786c\u76d8\u4e0a\u7684\uff09\u5b9e\u9645\u5b58\u50a8\u503c\u4e0d\u4f1a\u53d1\u751f\u4efb\u4f55\u53d8\u5316\uff0c\u5e76\u4e14\u4e0d\u4f1a\u5f71\u54cd\u8fd9\u4e24\u4e2a\u5bf9\u8c61\u7684\u7ee7\u627f\u5173\u7cfb\u3002\n\n2\u3001\u5f53\u6211\u4eec\u6b32\u4fee\u6539\u4efb\u610f\u4e00\u4e2a\u5bf9\u8c61\u7684\u5c5e\u6027\u503c\u65f6\uff0c\u9664\u4e86\u4f7f\u7528 oodb\uff08\u5373\u672c\u8f6f\u4ef6\uff09\u7684\u63a5\u53e3\u4fee\u6539\u4ee5\u5916\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 Navicat \u7b49\u7ba1\u7406\u5de5\u5177\u624b\u52a8\u4fee\u6539\uff0c\u4e8c\u8005\u7684\u6548\u679c\u662f\u5b8c\u5168\u4e00\u81f4\u7684\u3002\n\n## \u6761\u4ef6\u7b5b\u9009\n\n### \u793a\u4f8b\u4e00\uff1a\u7406\u89e3\u6761\u4ef6\u7b5b\u9009\u7684\u57fa\u672c\u8303\u5f0f\n\n\u7b5b\u9009\u3010\u5e74\u9f84>13\uff0c\u4e14\u89c6\u529b\u22674.6\uff0c\u4e14\u6027\u522b\u4e3a\u5973\u3011\u7684\u6570\u636e\uff0c\u5e76\u8fdb\u884c\u67e5\u6539\u5220\uff1a\n\n**\u67e5\u8be2**\uff1a`sheet[mc.\u5e74\u9f84 > 13][mc.\u89c6\u529b >= 4.6][mc.\u6027\u522b == '\u5973'].find( )`\n\n**\u4fee\u6539**\uff1a`sheet[mc.\u5e74\u9f84 > 13][mc.\u89c6\u529b >= 4.6][mc.\u6027\u522b == '\u5973'].update( {'\u5e74\u7ea7':'\u4e94\u5e74\u7ea7', '\u7231\u597d':'\u753b\u753b,\u8df3\u7ef3'} )`\n\n**\u5220\u9664**\uff1a`sheet[mc.\u5e74\u9f84 > 13][mc.\u89c6\u529b >= 4.6][mc.\u6027\u522b == '\u5973'].delete( )`\n\n### \u7b5b\u9009\u64cd\u4f5c\u6e05\u5355\n\n| **\u4ee3\u7801**                                                                 | \u89e3\u91ca                                            |\n| ------------------------------------------------------------------------------ | ----------------------------------------------- |\n| mc.\u5e74\u9f84 > 10                                                                   | \u5927\u4e8e                                            |\n| mc.\u5e74\u9f84 >= 10                                                                  | \u5927\u4e8e\u6216\u7b49\u4e8e                                      |\n| mc.\u5e74\u9f84 < 10                                                                   | \u5c0f\u4e8e                                            |\n| mc.\u5e74\u9f84 <= 10                                                                  | \u5c0f\u4e8e\u6216\u7b49\u4e8e                                      |\n| mc.\u5e74\u9f84 == 10                                                                  | \u7b49\u4e8e                                            |\n| mc.\u5e74\u9f84 != 10                                                                  | \u4e0d\u7b49\u4e8e                                          |\n| mc.\u5e74\u7ea7 == mf.isin( '\u521d\u4e09', '\u9ad8\u4e8c' )                                           | \u82e5\u5b57\u6bb5\u503c\u662f\u4f20\u5165\u503c\u7684\u6210\u5458\uff0c\u5219\u7b26\u5408                  |\n| mc.\u5e74\u9f84 == mf.notin( 10, 30, 45 )                                              | \u82e5\u5b57\u6bb5\u503c\u4e0d\u662f\u4f20\u5165\u503c\u7684\u6210\u5458\uff0c\u5219\u7b26\u5408                |\n| mc.\u7231\u597d == mf.contain_all( '\u753b\u753b', '\u8db3\u7403' )                                    | \u82e5\uff08\u5217\u8868\uff09\u5b57\u6bb5\u503c\u5305\u542b\u4f20\u5165\u503c\u7684\u6240\u6709\u5143\u7d20\uff0c\u5219\u7b26\u5408    |\n| mc.\u7231\u597d == mf.contain_any( '\u753b\u753b', '\u8db3\u7403' )                                    | \u82e5\uff08\u5217\u8868\uff09\u5b57\u6bb5\u503c\u5305\u542b\u4f20\u5165\u503c\u7684\u81f3\u5c111\u4e2a\u5143\u7d20\uff0c\u5219\u7b26\u5408 |\n| mc.\u7231\u597d == mf.contain_none( '\u753b\u753b', '\u8db3\u7403' )                                   | \u82e5\uff08\u5217\u8868\uff09\u5b57\u6bb5\u503c\u4e0d\u5305\u542b\u4f20\u5165\u503c\u7684\u4efb\u4f55\u5143\u7d20\uff0c\u5219\u7b26\u5408  |\n| mc.\u59d3\u540d == mf.re( '\u5c0f' )                                                       | \u6b63\u5219\u5339\u914d                                        |\n| \\[mc.\u5e74\u9f84 > 3\\][mc.\u5e74\u9f84 < 100]                                                 | \u4ea4\u96c6\uff08\u65b9\u5f0f\u4e00\uff09                                  |\n| [ (mc.\u5e74\u9f84 > 3) & (mc.\u5e74\u9f84 < 100) ]                                            | \u4ea4\u96c6\uff08\u65b9\u5f0f\u4e8c\uff09                                  |\n| [(mc.\u5e74\u9f84<30)&#124; (mc.\u5e74\u9f84>30) &#124; (mc.\u5e74\u9f84==30)\u00a0&#124; (mc.\u5e74\u9f84==None)] | \u5e76\u96c6                                            |\n| [ (mc.\u5e74\u9f84 > 3) - (mc.\u5e74\u9f84 > 100) ]                                            | \u5dee\u96c6                                            |\n| [ ~(mc.\u5e74\u9f84 > 100) ]                                                           | \u8865\u96c6                                            |\n\n\u6ce8\uff1a\n\n1\u3001isin\u3001notin \u7528\u4e8e\u5224\u65ad\uff08\u666e\u901a\uff09\u5b57\u6bb5\u7684\u503c\u662f\u5426\u4f20\u5165\u503c\u7684\u6210\u5458\uff0c\u9488\u5bf9\u666e\u901a\u5b57\u6bb5\u3002\n\n2\u3001contain_any\u3001contain_none \u7528\u4e8e\u5224\u65ad\u4f20\u5165\u503c\u662f\u5426\uff08\u5217\u8868\uff09\u5b57\u6bb5\u7684\u503c\u7684\u6210\u5458\uff0c\u9488\u5bf9\u5217\u8868\u5b57\u6bb5\u3002\n\n3\u3001isin\u3001notin\u3001contain_all\u3001contain_any\u3001contain_none \u7684\u4f20\u5165\u503c\u90fd\u4e0d\u5fc5\u662f\u540c\u7c7b\u578b\u7684\u6570\u636e\uff0c\u4ee5 isin \u4e3a\u4f8b\uff1a\u53ef\u4ee5\u8fd9\u6837\u4f7f\u7528\uff1amc.tag == mf.isin( 3, 3.5, '\u5b66\u751f', None )\uff0c\u4f20\u5165\u503c\u542b\u6709 int\u3001float\u3001str\u3001NoneType \u7b49\u591a\u79cd\u7c7b\u578b\u3002\n\n4\u3001\u6210\u5458\u8fd0\u7b97\u7b26\u672a\u4f20\u5165\u4efb\u4f55\u503c\u65f6\u7684\u5904\u7406\u65b9\u5f0f\uff1a\n\n| **\u4ee3\u7801**                | **\u5904\u7406\u65b9\u5f0f** |\n| ----------------------------- | ------------------ |\n| mc.\u5e74\u7ea7 == mf.isin( )         | \u6240\u6709\u6570\u636e\u90fd \u4e0d\u7b26\u5408  |\n| mc.\u5e74\u7ea7 == mf.notin( )        | \u6240\u6709\u6570\u636e\u90fd \u7b26\u5408    |\n| mc.\u7231\u597d == mf.contain_all( )  | \u6240\u6709\u6570\u636e\u90fd \u7b26\u5408    |\n| mc.\u7231\u597d == mf.contain_any( )  | \u6240\u6709\u6570\u636e\u90fd \u4e0d\u7b26\u5408  |\n| mc.\u7231\u597d == mf.contain_none( ) | \u6240\u6709\u6570\u636e\u90fd \u7b26\u5408    |\n\n5\u3001\u56db\u79cd\u96c6\u5408\u8fd0\u7b97\u53ef\u4ee5\u76f8\u4e92\u5d4c\u5957\uff0c\u4e14\u53ef\u4ee5\u65e0\u9650\u5d4c\u5957\u3002\n\n### \u793a\u4f8b\u4e8c\uff1a\u7406\u89e3\u5e76\u96c6\u3001\u4ea4\u96c6\u3001\u8865\u96c6\u7684\u4f7f\u7528\n\n\u7b5b\u9009\u3010\u5e74\u9f84>13\u6216\u89c6\u529b\u22674.6\u3001\u4e14\u59d3\u540d\u542b\u6709\u2018\u5c0f\u2019\u3001\u4e14\u5e74\u9f84\u4e0d\u9ad8\u4e8e15\u3011\u7684\u6570\u636e\uff1a\n\n**\u67e5\u8be2**\uff1a`sheet[(mc.\u5e74\u9f84>13) | (mc.\u89c6\u529b>=4.6)][mc.\u59d3\u540d == mf.re('\u5c0f')][~(mc.\u5e74\u9f84>15)].find( )`\n\n**\u4fee\u6539**\uff1a`sheet[(mc.\u5e74\u9f84>13) | (mc.\u89c6\u529b>=4.6)][mc.\u59d3\u540d == mf.re('\u5c0f')][~(mc.\u5e74\u9f84>15)].update( {'\u5e74\u7ea7':'\u521d\u4e09'} )`\n\n**\u5220\u9664**\uff1a`sheet[(mc.\u5e74\u9f84>13) | (mc.\u89c6\u529b>=4.6)][mc.\u59d3\u540d == mf.re('\u5c0f')][~(mc.\u5e74\u9f84>15)].delete( )`\n\n### \u6839\u636e\u5b50\u5143\u7d20\u8fc7\u6ee4\n\n\u53ef\u4f7f\u7528  mc.xxx.xxx.xxx...  \u7684\u5f62\u5f0f\u6765\u8868\u793a\u5b50\u5b59\u5143\u7d20\u3002\n\n\u67e5\u8be2\u3010\u8bed\u6587\u6210\u7ee9>80\u3011\u7684\u6570\u636e\uff1a\n\n```python\nsheet[mc.\u6210\u7ee9.\u8bed\u6587 > 80].find()\n```\n\n## \u7279\u6b8a\u5b57\u6bb5\u540d\u7684\u8868\u793a\u65b9\u6cd5\n\nMongoDB \u652f\u6301\u5404\u79cd\u7279\u6b8a\u7684\u5b57\u6bb5\u540d\uff0c\u5982\uff1a\u6570\u5b57\u3001\u7b26\u53f7\u3001emoji \u8868\u60c5\uff0c\u8fd9\u4e9b\u5b57\u7b26\u5728 Python \u4e2d\u4e0d\u662f\u5408\u6cd5\u53d8\u91cf\u540d\uff0c\u56e0\u6b64\u4f7f\u7528  mc.1\u3001mc.+  \u7b49\u683c\u5f0f\u4f1a\u62a5\u9519\uff0c\u53ef\u7528  mc['1']\u3001mc['+']\u3001mc['\ud83d\udc48']  \u8fd9\u79cd\u683c\u5f0f\u4ee3\u66ff\u3002\n\n## \u5b57\u6bb5\u63d0\u793a\n\n\u53d8\u91cf mc \u65e0\u5b57\u6bb5\u63d0\u793a\u529f\u80fd\uff0c\u8f93\u5165\u2018mc.\u2019\u540e\uff0c\u7f16\u8f91\u5668\u4e0d\u4f1a\u63d0\u793a\u53ef\u9009\u5b57\u6bb5\u3002\n\n\u4e3a\u4e86\u83b7\u5f97\u5b57\u6bb5\u63d0\u793a\u529f\u80fd\uff0c\u53ef\u81ea\u5efa\u4e00\u4e2a\u2018mc2\u2019\uff1a\n\n```python\nclass mc2(mc):\n    \u59d3\u540d = \u5e74\u9f84 = \u5e78\u8fd0\u6570\u5b57 = None\n    class \u6210\u7ee9:\n        \u8bed\u6587 = \u6570\u5b66 = None\n\nsheet[mc.\u59d3\u540d == '\u5c0f\u738b'][mc2.\u5e74\u9f84 > 10].find()\nsheet[mc.\u59d3\u540d == '\u5c0f\u738b'][mc2.\u6210\u7ee9.\u8bed\u6587 > 80].find()\n```\n\n\u6ce8\uff1a\n\n1\u3001mc2 \u4e0e mc \u7528\u6cd5\u5b8c\u5168\u4e00\u81f4\uff0c\u53ef\u6df7\u7528\u3002\n\n2\u3001mc2 \u8bbe\u7f6e\u5b57\u6bb5\u63d0\u793a\u540e\uff0c\u4ec5\u5177\u5907\u63d0\u793a\u6548\u679c\uff0c\u800c\u4e0d\u4ea7\u751f\u4efb\u4f55\u5b9e\u9645\u7ea6\u675f\u3002\n\n## \u7edf\u8ba1 \u4e0e \u5220\u5e93\u5220\u8868\n\n| \u529f\u80fd                   | \u4ee3\u7801                        |\n| ---------------------- | --------------------------- |\n| \u7edf\u8ba1\u5e93\u7684\u6570\u91cf           | oom.len( )                  |\n| \u7edf\u8ba1\u8868\u7684\u6570\u91cf           | db.len( )                   |\n| \u7edf\u8ba1\u884c\u7684\u6570\u91cf           | sheet.len( )                |\n| \u7edf\u8ba1\u7b26\u5408\u6761\u4ef6\u7684\u884c\u7684\u6570\u91cf | sheet[ mc.age > 8\u00a0].len( ) |\n| \u83b7\u53d6\u5e93\u540d\u6e05\u5355           | oom.get_db_names( )         |\n| \u83b7\u53d6\u8868\u540d\u6e05\u5355           | db.get_sheet_names( )       |\n| \u5220\u9664\u67d0\u4e2a\u5e93             | db.delete_db( )             |\n| \u5220\u9664\u67d0\u5f20\u8868             | sheet.delete_sheet( )       |\n\n## \u8fed\u4ee3\u6240\u6709 \u5e93OOM \u548c \u8868OOM\n\n```python\nfor db in oom:\n    for sheet in db:\n        print(sheet.sheet_name)\n```\n\n## \u7279\u6b8a\u64cd\u4f5c\n\n### \u793a\u4f8b\uff1a\u81ea\u589e\n\n\u7531\u4e8e\u65b0\u5e74\u5230\u4e86\uff0c\u4ee4\u6240\u6709\u5b66\u751f\u7684\u5e74\u9f84\u589e\u52a0 1 \u5c81\uff1a\n\n```python\nsheet.update( {'\u5e74\u9f84': mo.inc( 1 )} )\n```\n\n### \u7279\u6b8a\u64cd\u4f5c\u6e05\u5355\uff1a\n\n| **\u8bed\u6cd5**        | **\u542b\u4e49**                                     |\n| --------------------- | -------------------------------------------------- |\n| mo.inc( 1.5 )         | \u81ea\u589e 1.5                                           |\n| mo.inc( -1.5 )        | \u81ea\u51cf 1.5                                           |\n| mo.add( 1, 2, 3 )     | \u5411\u5217\u8868\u5b57\u6bb5\u6dfb\u52a0\u5143\u7d20\uff0c\u4ec5\u5f53\u88ab\u6dfb\u52a0\u7684\u5143\u7d20\u4e0d\u5b58\u5728\u65f6\u624d\u6dfb\u52a0 |\n| mo.push( 1, 2, 3 )    | \u5411\u5217\u8868\u5b57\u6bb5\u6dfb\u52a0\u5143\u7d20\uff0c\u65e0\u8bba\u88ab\u6dfb\u52a0\u7684\u5143\u7d20\u662f\u5426\u5b58\u5728\u90fd\u6dfb\u52a0 |\n| mo.pull( 15 )         | \u4ece\u5217\u8868\u5b57\u6bb5\u5220\u9664 1 \u4e2a\u7b49\u4e8e 15 \u7684\u503c                    |\n| mo.popfirst           | \u4ece\u5217\u8868\u5b57\u6bb5\u5220\u9664\u7b2c 1 \u4e2a\u5143\u7d20                          |\n| mo.poplast            | \u4ece\u5217\u8868\u5b57\u6bb5\u5220\u9664\u6700\u540e 1 \u4e2a\u5143\u7d20                        |\n| mo.rename( '\u65b0\u540d\u79f0' ) | \u91cd\u547d\u540d\u5b57\u6bb5                                         |\n| mo.unset              | \u5220\u9664\u5b57\u6bb5                                           |\n| mo.delete             | \u5220\u9664\u5b57\u6bb5\uff08\u4e0e mo.unset \u7b49\u4ef7\uff09                       |\n\n\u793a\u4f8b\uff1a\n\n```python\nsheet[mc.\u59d3\u540d=='\u5c0f\u516d'].update({\n    '\u59d3\u540d': 'xiaoliu',          # \u4fee\u6539\u4e3a\u2018xiaoliu\u2019\n    '\u5e74\u9f84': mo.inc(6),          # \u81ea\u589e6\n    '\u5e78\u8fd0\u6570\u5b57': mo.push(666),   # \u6dfb\u52a0666\n    '\u89c6\u529b': mo.rename('\u773c\u529b'),  # \u5b57\u6bb5\u540d\u6539\u4e3a\u2018\u773c\u529b\u2019\n    '\u7c4d\u8d2f': mo.delete,          # \u5220\u9664\u6b64\u5b57\u6bb5\n    '\u6210\u7ee9.\u8bed\u6587': 60,            # \u6539\u4e3a60\u5206\n    '\u6210\u7ee9.\u6570\u5b66': mo.inc(-6)     # \u51cf6\u5206\n})\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "\u9762\u5411\u5bf9\u8c61\u6570\u636e\u5e93 \u2014\u2014 \u5f15\u5165\u4e86 Python \u4e2d\u7c7b\u7684\u7279\u6027\uff0c\u5982\uff1a\u7ee7\u627f\u3001\u91cd\u5199\u3001\u65b9\u6cd5\u3001\u52a8\u6001\u5c5e\u6027\u7b49\u3002",
    "version": "1.0.3",
    "project_urls": {
        "Source": "https://github.com/lcctoor/arts/tree/main/arts/oodb"
    },
    "split_keywords": [
        "oodbms",
        " oodbs",
        " oodb"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c83042c0aeb989200ff98da8a7ac5f57d1aae6d90e1803c55e7b65a8011d65ad",
                "md5": "9f0e92af872e3a9db1eecdf3d635f1e2",
                "sha256": "37b5bd3dba3b6b200a8e9a35142cea299ebff8c2df8b87acc18f11d03a0541e5"
            },
            "downloads": -1,
            "filename": "oodb-1.0.3-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9f0e92af872e3a9db1eecdf3d635f1e2",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 12065,
            "upload_time": "2024-07-28T23:47:21",
            "upload_time_iso_8601": "2024-07-28T23:47:21.290393Z",
            "url": "https://files.pythonhosted.org/packages/c8/30/42c0aeb989200ff98da8a7ac5f57d1aae6d90e1803c55e7b65a8011d65ad/oodb-1.0.3-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b5ef1aba0827a1bffdc2c16b0b0447eb994c695335f6db91160a26934da3e0e5",
                "md5": "52914621d82b73cff4dfe3dcafb579f9",
                "sha256": "40f9e1a99b41659108b72c8a46649e56939a8145943492c6ca443d1d57191799"
            },
            "downloads": -1,
            "filename": "oodb-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "52914621d82b73cff4dfe3dcafb579f9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 26801,
            "upload_time": "2024-07-28T23:47:23",
            "upload_time_iso_8601": "2024-07-28T23:47:23.870117Z",
            "url": "https://files.pythonhosted.org/packages/b5/ef/1aba0827a1bffdc2c16b0b0447eb994c695335f6db91160a26934da3e0e5/oodb-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-28 23:47:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "lcctoor",
    "github_project": "arts",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "oodb"
}
        
Elapsed time: 0.67718s