如何通过python manage.py shell异步执行Django脚本并保证运行顺序?
你遇到的现象本质不是异步执行导致的,Django 原生同步 ORM 的所有数据库操作默认都是同步阻塞的,前一个操作完成后才会执行下一个。两种执行模式返回结果不同,是因为python manage.py shell < import.py的批量输入模式和逐行输入模式的事务提交逻辑、ORM 缓存策略存在差异:
- 逐行输入 shell 时,每一行代码执行完成后都会自动提交事务,且每次查询都会拉取最新的数据库数据
- 批量输入脚本时,所有代码会被当成一个执行块处理,可能出现事务未及时提交、ORM 缓存旧关联数据的问题,导致计算
num_grandchildren时拿到的是未更新的num_children值
你可以按照以下方案修改import.py即可得到正确结果:
from django.db import transaction # 注意根据你的实际项目路径替换模型导入路径 from myapp.models import Parent, Person # 用事务块包裹前序写入操作,保证所有操作全部成功才提交 with transaction.atomic(): parent = Parent.objects.create(id=1, num_grandchildren=0) person1 = Person.objects.create(id=2, parent=parent) person2 = Person.objects.create(id=3, parent=parent) person3 = Person.objects.create(id=4, parent=parent) persons = Person.objects.all() Person.objects.generate_num_children(persons) # 事务提交完成后,刷新parent实例的缓存,避免使用内存中的旧关联数据 parent.refresh_from_db() # 执行计算写入操作 parent.generate_num_grandchildren()
如果仍有问题,建议你不要再使用shell < 脚本的方式执行这类数据操作脚本,更稳定的方式是编写 Django 自定义管理命令执行,不会出现 shell 输入模式的事务异常问题。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

