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()

浙公网安备 33010602011771号