注意,pypadb 0.1.14 版本破坏性变更。
命名更改:
pypadb.conf.db_configurer -> pypadb.conf.db (module)
pypadb.conf.table_configurer -> pypadb.conf.table (module)
pypadb.conf.db.DbConfigurer -> pypadb.conf.db.DbConfig (class)
pypadb.conf.table.TableConfig -> pypadb.conf.table.TableConfig (class)
pypadb.conf.db.db_configurer -> pypadb.conf.db.db_config (attribute)
pypadb.conf.table.tables -> pypadb.conf.table.table_pool (attribute)
pypadb 提供了 @insert
、@update
、@delete
、@select
四个装饰器来扩展函数。
有如下表结构:
create table test
(
id int unsigned auto_increment primary key,
content varchar(255) null,
ctime bigint null,
mtime bigint null
);
实体类如下:
class Test(BaseModel):
id: Optional[int]
content: str
ctime: Optional[int]
mtime: Optional[int]
- 实体类须继承
pydantic.BaseModel
。 - 实体类的属性须添加类型注释。
- 可以为
None
的属性或- 不在数据库表里的属性须用Optional
包裹。
@insert
from pypadb.decorator import insert
@insert('insert into test(content,ctime)')
def ins_test(test: Union[list[Test], Test]):
# 在 insert 前修改 ctime(创建时间)为当前时间
test.ctime = int(datetime.datetime.now().timestamp() * 1000)
# 单个插入
ins_test(Test(content='wow'))
# 批量插入
ins_test([Test(content='wow'), Test(content='123456')])
@insert
装饰器接受一个参数 sql: str
,要表明插入时的列名。
被装饰的函数只接受一个参数,可以为 Test
或者 list[Test]
,装饰器在处理的时候会判断是否进行批量插入。
函数体可以为 pass
,如果函数体不为空,则会在插入前调用函数,例如上面的代码,在插入前初始化 ctime
字段为当前时间。对于 list[Test]
,装饰器同样会在插入前对每一个实体类进行处理。
函数的返回值是修改的最后一行主键值。
@update
from pypadb.decorator import update
@update('update test')
def upd_test(test: Test):
# 在 update 前修改 mtime (修改时间)为当前时间
test.mtime = int(datetime.datetime.now().timestamp() * 1000)
# 实体类,查询条件1,查询条件2 ...
upd_test(Test(content='wuhu'), id=1)
@update
接受一个参数 sql: str
,只需要写上需要更新的表,装饰器会根据传进来的实体对象动态生成 sql 语句。即实体对象的属性值为 None
、空数组或者空字符串时,@update
会忽略这一属性。需要注意的是,若属性值为 0 时,@update
也会进行更新。
函数体可以为 pass
,如果函数体不为空,则会在插入前调用函数,例如上面的代码,在插入前初始化 mtime
字段为当前时间。对于 list[Test]
,装饰器同样会在插入前对每一个实体类进行处理。
被装饰的函数接受一个参数作为实体对象,还有若干指定参数作为查询条件。
函数的返回值是修改时的主键值。
@delete
from pypadb.decorator import delete
@delete('delete from test where id=%(id)s')
def del_test(id: int = 0):
pass
@delete
装饰器接受一个值 sql: str
,要写全。装饰器会把函数的参数列表和调用函数传进来的值做匹配,处理成一个 dict
交给 pymysql
处理。
@delete
同样支持在删除前调用被装饰的函数。
@select
from pypadb.decorator import select
# 查询返回单个对象
@select('select * from test where id=%(id)s', data_type=Test)
def sel_test_one(id: int) -> Test:
pass
# 查询返回数组
@select(
'select * from test where content like concat(\'%%\',%(concat)s,\'%%\')',
data_type=Test
)
def sel_test_many(concat: str) -> list[Test]:
pass
@select
装饰器接受 2 个参数,处理 sql 语句和 @delete
一样,第二个参数 data_type
是为了将查询出来的数据包装成对象。
@select
装饰器会通过反射的方式拿到函数返回值的类型注释,判断其是否为 list
来决定返回值是否为 list
。若查询结果有多个,函数的返回值类型注释不是 list
的话,装饰器只会取结果集中的首行包装成对象返回。
被装饰的函数不需要有函数体,对函数体不做处理。被装饰的函数的参数列表不需要加上类型注释,当然加了更严谨。
2022-01-29