tortoise orm 事务处理 外键 配置
_assign为查询返回的QuerySet,licensee为外键,在这条件下,注意下列结果:
_assign.licensee 值为QuerySet
_assign.licensee_id 值为int
结论:从querySet取外键id值时,要加上 _id;
同时可以推断出取其他字段值是,为 _assign.licensee_字段名
外键最关键的教训: 1、查找时,直接使用field名; 2、create时,要加上 _id;
3、从querySet取外键id值时,要加上 _id;
提醒:查找时使用外键,无论正向或反向, 当使用id值时,直接当普通字段使用即可; 当使用其他字段值时,要加止双下标线。 class Xyuser(Model): id = fields.BigIntField(pk=True, verbose_name='ID') username = fields.CharField(max_length=30, db_index=True, verbose_name='用户名') mobile = fields.BigIntField(db_index=True, verbose_name='手机号码') company_admin: fields.ReverseRelation["Company"] class Company(Model): id = fields.BigIntField(pk=True) name = fields.CharField(unique=True, max_length=150, verbose_name='公司名称') admin: fields.OneToOneRelation[Xyuser] = fields.OneToOneField( "models.Xyuser", related_name="company_admin", on_delete=fields.CASCADE,verbose_name='锁管理员') creator: fields.ForeignKeyRelation[Xyuser] = fields.ForeignKeyField( "models.Xyuser",related_name="company_creator",on_delete=fields.CASCADE,verbose_name='公司创建者') 正向使用外键 instance = await Company.filter(id=company_id, creator=user_id).first() 反向外键查找 xyuser = await Xyuser.filter(company_admin=company_id).update(**dict(is_xyerased=True))
连接mysql Tortoise.init_models(["models"], "models", ) register_tortoise( app, db_url="mysql://root:********@121.43.***.***:****/tortoise?charset=utf8", modules={"models": ["models"]}, generate_schemas=True, add_exception_handlers=True, )
时间的使用: print(time.time()) date = int(round(time.time() * 1000)) print(date) starttime = datetime(2022, 8, 26, 19, 31, 48, 749964) endtime = datetime.now() print(repr(endtime)) ti = endtime - starttime print(ti.seconds) 结果: 1661513588.2224925 1661513588222 datetime.datetime(2022, 8, 26, 19, 33, 8, 222492) 79
@app.middleware("http") async def check_url_path(request: Request, call_next, token: str = Header(...)): user_ip = request.client.host url_path = request.url.path path = url_path[(url_path.rfind('/') + 1):] token = request.headers.get('authorization', '') token = token[7:] if token else token # paths = list(r.URLtoROLE.keys()) response = await call_next(request) return response
定时任务
def my_sched(i=1): sched = AsyncIOScheduler() @sched.scheduled_job('interval', id='my_job', seconds=180) async def my_job(): _dept = await Dept.first().values() print(_dept) print(f'{datetime.now():%H:%M:%S} MYSQL保持连接定时任务。 ') sched.start() th1 = MyThread(my_sched, (1,), my_sched.__name__) th1.start() th1.join()
pip install python-multipart
第二种 (推荐) 使用 pipreqs
,github地址为: https://github.com/bndr/pipreqs
# 安装 pip install pipreqs # 在当前目录生成 pipreqs . --encoding=utf8 --force
2.生成方法
方法一:整个环境下的安装包都保存到requirements.txt中
pip freeze > requirements.txt
作用范围:pip的freeze命令保存了保存当前Python环境下所有类库包,包括那些你没有在当前项目中使用的类库。 (如果你没有的virtualenv)
生成的requirements.txt:速度非常快,不到1s
create方法时(正向):
反向代码提示:
在使用外键的时候,我们需要获取到反向代码提示(即被绑定的model查询绑定model),这个时候需要使用relation字段来提示,(其实你不加也没啥关系,只是个提示作用,在django里面是编辑器和插件提前内置了相关字段所以不用手写)
示例代码如下:
from tortoise.models import Model from tortoise import fields class Tournament(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255) events: fields.ReverseRelation["Event"]#仅用于代码提示,注意events必须和Event里面的外键指定的related_name同名 class Event(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255) tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField( "models.Tournament", related_name="events" ) participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField( "models.Team", related_name="events", through="event_team" )#注意多对多,两个model里面都要写,虽然复杂了点,但是有代码提示还是很合算的。。through在django里面是指定多对多表的名字和功能,
需要手动创建,这里可能是示例代码不全吧。。得测试 class Team(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255) events: fields.ManyToManyRelation[Event]#反向关系,
class Uusers(Model): id = fields.IntField(pk=True) name = fields.IntField() dept: fields.ReverseRelation["Dept"] class Dept(Model): id = fields.IntField(pk=True) name = fields.IntField() user = fields.ForeignKeyField('models.Uusers', on_delete=fields.CASCADE, related_name='dept', verbose_name='所属部门')
# todo 外键正向查找,使用非id字段 # users = await Dept.filter(user__name=79997).values(*fields) # todo 外键正向查找,使用id字段 users = await Dept.filter(user_id=90001).values() # todo 外键反向查找示例 # users = await Uusers.filter(dept__id=5).values()
事务处理
#!/usr/bin/python # -*- coding:UTF-8 -*- import pymysql host = "localhost" username = "01kuaixue" password = "123456" db_name = "test" #创建connect对象 connect = pymysql.connect(host,username,password,db_name) #获取游标对象 cursor=connect.cursor() #正确的sql语句 insert_sql1 = "insert into users(name,age) values('',1)" #错误的sql语句 insert_sql2 = "insert into users(name,age) values( 1)" try: cursor.execute(insert_sql1) cursor.execute(insert_sql2) #执行成功提交更改数据 connect.commit() except pymysql.err.InternalError: #执行失败回滚数据 connect.rollback() cursor.close() connect.close()
try: cursor.execute(sql_1) cursor.execute(sql_2) cursor.execute(sql_3) except Exception as e: connect.rollback() # 事务回滚 print('事务处理失败', e) else: connect.commit() # 事务提交 print('事务处理成功', cursor.rowcount)# 关闭连接 cursor.close() connect.close()