Package: think-sql
ThinkSQL 类似 ThinkPHP 的数据库引擎Installpip install think-sqlHow to use1. simple demoDatabase:testTable:userexample dict paramsfromthink_sql.databaseimportDBconfig={'host':'127.0.0.1','port':3306,'username':'root','password':'root','database':'test',}withDB(config)asdb:data=db.table('user').where('id',1).find()print(data)example dsn strfromthink_sql.databaseimportDBwithDB("root:'root'@127.0.0.1:3306/test")asdb:data=db.table('user').where('id',1).find()print(data)example DBConfigfromthink_sql.databaseimportDBfromthink_sql.utilimportDBConfigconfig=DBConfig(host='127.0.0.1',port=3306,username='root',password='root',database='test',)withDB(config)asdb:data=db.table('user').where('id',1).find()print(data)result{"id":1,"username":"hbh112233abc","age":"36","address":"FUJIAN.XIAMEN"}2. Introductionthink_sql.database.DBinit(config:Union[str,dict,DBConfig],params={})init database, return DB instanceconfig:Union[str,dict,DBConfig]str:username:'password'@host:port/databasedict:{'host':'127.0.0.1','port':3306,'username':'root','password':'root','database':'test'}DBConfig:DBConfig(host='127.0.0.1',port=3306,username='root',password='root',database='test')params:dict pymysql connect other paramsconnect()
connect database useinitparamstable(table_name):Table
return class Table <think_sql.table.Table>check_connected():bool
check connected, try reconnect databasequery(sql,params=())
query sql return cursor.fetchall List[dict]execute(sql,params=())
execute sql write operate(ex:insert,update,delete,...)think_sql.table.Tableinit(connector: Connection,cursor: Cursor,table_name: str,debug: bool = True)init()
initialize query conditiondebug(flag=True)
set debug flagset_cache_storage(storage: CacheStorage)
set cache storage ex: Rediscache(key: str = None, expire: int = 3600)
use cache at querycursor(sql: str, params: list = []) -> Cursor
return cursor objectget_last_sql() -> str
return last sql stringget_lastid() -> str
return last row idget_rowcount() -> int
return affect rows countfetch_sql(flag: bool = True)
set fetch sql flag,if flag = True thenqueryandexecutewill only return sqlbuild_sql(operation: str, params: list = []) -> str
return build sqlquery(sql: str, params: list = []) -> list
execute read operation sql and return cursor.fetchall()
whenfetch_sql=True then return sql and not execute the sqlexecute(sql: str, params: list = []) -> int
execute write operation sql and return affect rows count
whenfetch_sql=True then return sql and not execute the sqlwhere(field: Union[str, list, tuple], symbol: str = '', value: Any = None)
set query conditions, support multipe usewhere(field,value)wherefield=valuewhere(field,symbol,value)wherefieldsymbolvaluewhere([[field1,symbol1,value1],[field2,symbol2,value2]])wherefield1symbol1value1andfield2symbol2value2where(field1,symbol1,value1).where(field2,symbol2,value2)wherefield1symbol1value1andfield2symbol2value2symbolsymbolanotherdemo=eq,=where('id','=',1)<>neq,!=,<>where('id','<>',1)>gt,>where('id','>',1)>=egt,>=where('id','>=',1)<lt,<where('id','<',1)<=elt,<=where('id','<=',1)inin,not inwhere('id','in',[1,2,3])betweenbetween,not betweenwhere('id','between',[1,5]) where('id','between','1,5') where('id','between','1 and 5')likelike,not likewhere('name','like','%hbh%')nullis null,nullwhere('remark','is null')not nullis not null,not nullwhere('remark','is not null')existsexists,not existswhere('remark','exists')expexpwhere('id','exp','in (1,2,3)')where_or(field: Union[str, list], symbol: str = '', value: Any = None)where('id',1).where_or('id',5)where id = 1 or id = 5limit(start: int, step: int = None)
LIMIT start,steppage(index: int = 1, size: int = 20)
LIMIT index*size-1,sizeorder(field: str, sort: str = 'asc')
ORDER BY field sortgroup(field:str)
GROUP BY fielddistinct(field:str)
SELECT DISTINCT fieldfield(fields: Any, exclude: bool = False)
SELECT fields
ifexclude=True then select the fields of table (exlude:fields)select(build_sql: bool = False) -> list
return select query result
ifbuild_sql=True then return sqlfind()
return select ... limit 1value(field: str)
return the field of first rowcolumn(field: str,key: str = '')column('name')return ['hbh','mondy']column('name,score')return [{'hbh':80},{'mondy':88}]column('score','name')return {'hbh':80, 'mondy':88}column('id,score','name')return {
'hbh':{'id':1,'score':80},
'mondy':{'id':2,'score':88}
}alias(short_name: str = '')
set alias table_namejoin(table_name: str, as_name: str = '', on: str = '', join: str = 'inner', and_str: str = '')table_namejoin table_nameas_namealias short_table_name fortable_nameonjoin conditionjoinjoin type in 'INNER', 'LEFT', 'RIGHT', 'FULL OUTER'and_strand condition
demodb.table('table1').alias('a').join('table2','b','a.id=b.a_id','left').join('table3','c','c.a_id=a.id').field('a.id,a.name,b.id as b_id,b.score,c.id as c_id,c.remark').where('a.id',1).find()sqlSELECTa.id,a.name,b.idASb_id,b.score,c.idASc_id,c.remarkFROMtable1ASaLEFTJOINtable2ASbONa.id=b.a_idINNERJOINtable3AScONc.a_id=a.idWHEREa.id=1LIMIT1union(sql1: str, sql2: str, union_all: bool = False)
union sql1 and sql2union_all if union_all is True thenUNION ALLdemosql1=db.table('table1').field('name,score').where('status',1).select(build_sql=True)sql2=db.table('table2').field('name,score').where('status',1).select(build_sql=True)result=db.table().union(sql1,sql2).where('score','>',60).select()sqlSELECT*FROM(SELECT`name`,`score`FROMtable1WHERE`status`=1)UNION(SELECT`name`,`score`FROMtable2WHERE`status`=1)WHEREscore>60insert(data: Union[dict, List[dict]], replace: bool = False) -> int
insert data to databasedatadict: insert one record; list: insert multiple recordsreplacebool ifreplaceis True then useREPLACE INTOdemoinsert one recorddb.table('table1').insert({'name':'test','score':100})INSERTINTOtable1(`name`,`score`)VALUES('test',100)insert multiple recordsdb.table('table1').insert([{'name':'test','score':100},{'name':'test2','score':101}])INSERTINTOtable1(`name`,`score`)VALUES('test',100),('test2',101)replace modedb.table('table1').insert({'id':1,'name':'test','score':100},replace=True)REPLACEINTOtable1(`id`,`name`,`score`)VALUES(1,'test',100)update(data: dict, all_record: bool = False) -> int
update datadatadict you want update dataall_recordbool ifall_recordis False then you must set update condition; if you want to update all records then you need setall_record= Truedelete(all_record: bool = False) -> int
delete recordall_recordbool ifall_recordis False then you must set delete condition; if you want to delete all records then you need setall_record= Trueinc(field: str, step: Union[str, int, float] = 1) -> intincreasefield+stepdec(field: str, step: int = 1) -> intdecreasefield-stepmax(field: str) -> Union[int, float]get the max value offieldsum(field: str) -> Union[int, float, Decimal]get the sum value offieldavg(field: str) -> Union[int, float, Decimal]get the avg value offieldcount(field: str = '*') -> intget the count of recordscopy_to(new_table: str = None, create_blank_table: bool = False) -> intcopy data tonew_tablenew_tableifnew_tableis None thennew_tablewill auto set like{table_name}_copycreate_blank_tablebool ifcreate_blank_tableis True then only create a blank table like current table.demodb.table('user').field('name,score').where('score','>',60).copy_to('good_boy')sqlSELECT`name`,`score`INTO`good_boy`FROM`user`WHEREscore>60insert_to(new_table: str, fields: Union[str, list, tuple] = None) -> intINSERTINTO{new_table}SELECT{select_fields}FROM{table}{join}WHERE{where}{group}{order}{limit}exists(self) -> boolcheck record exists with some query conditions, it useSELECT 1 FROM {table} {join} WHERE {where} LIMIT 1batch_update(data:List[dict],key:str) -> intbatch update multiple recordsdemodata=[{'id':1,'score':66},{'id':2,'score':59},{'id':3,'score':86},{'id':4,'score':90},]db.table('user').batch(data,key='id')sqlupdate`user`setscore=66whereid=1;update`user`setscore=59whereid=2;update`user`setscore=86whereid=3;update`user`setscore=90whereid=4;support transactionfromthink_sql.databaseimportDBdb_dsn="root:'password'@127.0.0.1:3306/database"withDB(db_dsn)asdb:# result: insert two records into databasewithdb.start_trans():db.table('user').insert({'name':'think_sql1','score':98})db.table('user').insert({'name':'think_sql2','score':99})# result: nothing insertedwithdb.start_trans():db.table('user').insert({'name':'think_sql1','score':98})db.table('user').insert({'name':'think_sql2','score':99})raiseException('error')# The above operation does not affect subsequent operations.db.table('user').insert({'name':'think_sql3','score':100})sql_helperRef:hcymysql/sql_helperfromthink_sql.databaseimportDBfromthink_sql.sql_helperimporthelpdb_dsn="root:'password'@127.0.0.1:3306/database"withDB(db_dsn)asdb:sql="slow query sql"help(db,sql)result1)输入的SQL语句是：
----------------------------------------------------------------------------------------------------
SELECT*
FROMhy_cabrecs
WHEREfinished_count>0----------------------------------------------------------------------------------------------------2)EXPLAIN执行计划:
+------+---------------+------------+--------------+--------+-----------------+-------+-----------+-------+--------+------------+-------------+|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|+======+===============+============+==============+========+=================+=======+===========+=======+========+============+=============+|1|SIMPLE|hy_cabrecs|None|ALL|None|None|None|None|14422|33.33|Usingwhere|+------+---------------+------------+--------------+--------+-----------------+-------+-----------+-------+--------+------------+-------------+3)索引优化建议：
----------------------------------------------------------------------------------------------------
取出表【hy_cabrecs】where条件字段【finished_count】100000条记录，重复的数据有：【16093】条，没有必要为该字段创建索引。【hy_cabrecs】表，无需添加任何索引。parseparse alter sqlfromthink_sqlimportparsesql="""alter     tableslow_log_testaddiii int not null default 0  comment   'a';"""print(parse.alter_sql(sql))result:{"table":"slow_log_test","field":"iii","field_type":"int","is_null":"NOT NULL","default":"0","comment":"'a'","after":""}Developmentpoetry 包管理器官网Python 包管理之 poetry 的使用Python 包管理之 poetry 基本使用# 配置虚拟环境在项目目录下
poetry config virtualenvs.path true
# 安装依赖
poetry install
# 进入虚拟环境
poetry shellpoetry command名称功能new创建一个项目脚手架，包含基本结构、pyproject.toml 文件init基于已有的项目代码创建 pyproject.toml 文件，支持交互式填写install安装依赖库update更新依赖库add添加依赖库remove移除依赖库show查看具体依赖库信息，支持显示树形依赖链build构建 tar.gz 或 wheel 包publish发布到 PyPIrun运行脚本和代码unit testpytest --cov --cov-report=htmlpublishpoetry build
poetry config pypi-token.pypi "your pypi.org api token"
poetry publish -n