我有一些处理Django用户的信号处理程序。另外我使用南方。这些信号处理程序取决于之前必须运行的一些迁移。以编程方式检查syncdb是否正在运行
当Django执行snycdb并创建admin用户时,这些迁移没有运行,信号处理程序引发异常。
我正在寻找一种方法来检测Django当前是否运行syncdb,以便信号handerls可以跳过执行。
我有一些处理Django用户的信号处理程序。另外我使用南方。这些信号处理程序取决于之前必须运行的一些迁移。以编程方式检查syncdb是否正在运行
当Django执行snycdb并创建admin用户时,这些迁移没有运行,信号处理程序引发异常。
我正在寻找一种方法来检测Django当前是否运行syncdb,以便信号handerls可以跳过执行。
我不认为有一种方法可以知道是否执行syncdb正在运行,但有一种方法来处理Python异常:
正好赶上和异常和pass
:
try:
# code that deals with django user
except ExceptionYouAreGetting:
# seems like syncdb is running, let's pass for now
pass
虽然这是一个选项,但我不想在处理程序中吞下一个DatabaseError,因为这也可能表示其他严重问题。 –
AFAIK无法检测syncdb是否正在运行,但是,当syncdb或loaddata正在运行时,您的信号将收到原始的额外参数。
@receiver(post_save, sender=ModelA)
def signal_handler(sender, **kwargs):
raw = kwargs.get('raw', False)
if not raw:
<do whatever>
这样,您可以跳过syncdb执行时要运行的信号。
只有在数据从夹具中加载时,原始参数才为真。然而,django在初始syncdb过程中创建的一些内容(如初始用户和默认网站)并未从fixtures加载,因此raw会像其他保存场景一样为False。 –
我陷阱DatabaseError异常,并检查我试图使用的模型的ContentType条目是否存在,如果它没有,我假设syncdb正在发生,否则回滚事务并重新引发原始异常。只有在引发DatabaseError时,此方法才会产生额外的DB访问权限。
with transaction.commit_on_success():
try:
content_type = ContentType.objects.get_for_model(kwargs['instance'])
for relation in WorkflowTypeRelation.objects.filter(content_type=content_type):
workflow_instance = WorkflowInstance.objects.create(content_object=kwargs['instance'],
workflow_type=relation.workflow_type)
except DatabaseError as database_error:
try:
ContentType.objects.get(model='workflowtyperelation')
except ContentType.DoesNotExist:
# Most probable running during syncdb phase,
# so ignore the exception
pass
except DatabaseError:
# ContentType model DB table doesn't exists,
# raise original exception
raise database_error
else:
# The ContentType model exists,
# there is something wrong with the DB
# raise original exception
transaction.rollback()
raise database_error
南有它的模型和一张表,它记录了哪些信息哪些是迁移已被毁掉,哪些不是。也许你可以用它来检查你需要的迁移是否已经运行? – Ski
这也是一个选项。但由于处理程序是用于保存相对经常保存的模型的保存后信号,因此我希望此时避免额外往返数据库。 –
我认为您可以安全地将这些信息存储在全局变量中,并在应用程序启动时只检索一次。 – Ski