diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index 1e134b46f82d..f653b18e0c70 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -23,7 +23,7 @@ from django.utils.dateparse import parse_datetime from django.utils.translation import gettext_lazy as _ from django.utils.functional import cached_property -from django.db import connection, transaction, ProgrammingError +from django.db import connection, transaction, ProgrammingError, IntegrityError from django.db.models.fields.related import ForeignObjectRel, ManyToManyField from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor, ManyToManyDescriptor from django.db.models.query import QuerySet @@ -1164,13 +1164,23 @@ def create_partition(tblname, start=None): try: with transaction.atomic(): with connection.cursor() as cursor: + r_tuples = cursor.execute(f"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = '{tblname}_{partition_label}');") + for row in r_tuples: # should only have 1 + for val in row: # should only have 1 + if val is True: + logger.debug(f'Event partition table {tblname}_{partition_label} already exists') + return + cursor.execute( - f'CREATE TABLE IF NOT EXISTS {tblname}_{partition_label} ' - f'PARTITION OF {tblname} ' - f'FOR VALUES FROM (\'{start_timestamp}\') to (\'{end_timestamp}\');' + f'CREATE TABLE {tblname}_{partition_label} (LIKE {tblname} INCLUDING DEFAULTS INCLUDING CONSTRAINTS); ' + f'ALTER TABLE {tblname} ATTACH PARTITION {tblname}_{partition_label} ' + f'FOR VALUES FROM (\'{start_timestamp}\') TO (\'{end_timestamp}\');' ) - except ProgrammingError as e: - logger.debug(f'Caught known error due to existing partition: {e}') + except (ProgrammingError, IntegrityError) as e: + if 'already exists' in str(e): + logger.info(f'Caught known error due to partition creation race: {e}') + else: + raise def cleanup_new_process(func):