开发者

Programmatically check if syncdb is running

开发者 https://www.devze.com 2023-04-13 00:17 出处:网络
I have some signal handlers that work on the Django user. Additionally I\'m using South. These signal handlers depends on some migrations th开发者_如何学Pythonat must run in before.

I have some signal handlers that work on the Django user. Additionally I'm using South. These signal handlers depends on some migrations th开发者_如何学Pythonat must run in before.

When Django executed snycdb and creates the admin user these migrations haven't run and the signal handlers raise an exception.

I'm searching for a way to detect if Django currently runs syncdb so that the signal handerls can skip execution.


I trap the DatabaseError exception and check if the ContentType entry for the model I'm trying to use exists, if it doesn't I assume syncdb is happening, otherwise rollback the transaction and re-raise the original exception. This method incurs in an extra DB access only when DatabaseError is raised.

    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


I don't think there is a way to know if syncdb is running, but there is a way to handle exceptions in python:

Just catch and exception and pass:

try:
    # code that deals with django user
except ExceptionYouAreGetting:
    # seems like syncdb is running, let's pass for now
    pass


AFAIK it's not possible to detect whether or not syncdb is running, however, when syncdb or loaddata is running, your signals will receive an extra argument raw.

@receiver(post_save, sender=ModelA)
def signal_handler(sender, **kwargs):
    raw = kwargs.get('raw', False)
    if not raw:
        <do whatever>

This way, you can skip signals to be run when syncdb is being executed.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号