英文:
error while updating table in MySQL : mysql.connector.errors.DatabaseError: 1412 (HY000): Table definition has changed, please retry transaction
问题
I am working on one personal project.
There is multiple similar questions on this forum however everyone is case specific.
In my case i am creating and loading temp table, i am joining that table with existing table in DB and updating the same table based on temp table results. while executing db.execute_insert_update()
it throws an exception : mysql.connector.errors.DatabaseError: 1412 (HY000): Table definition has changed, please retry transaction
> def _create_and_load_table(self, dataframe: DataFrame) -> str: #first_function
self._log_entry()
temp_table_name = self._generate_table_name()
table_schema = "partner_staging"
table_with_schema = f"{table_schema}.{temp_table_name}"
self.df_mgr.jdbc_write(dataframe=dataframe, dbtable=table_with_schema,
check_count_before_write=True)
self._log_exit()
return temp_table_name
def reconcile_partner_payments(self, dataframe: DataFrame) -> NoReturn: #second function
self.logger.info("Start reconcile_partner_payments")
self.logger.info(f"df_col:{dataframe.columns}")
partner_payment_ids = dataframe.select("partner_payment_id",
"effective_payroll_date").distinct()
self.logger.info(f"head:{partner_payment_ids.head(3)}")
self.logger.info(f"count:{partner_payment_ids.count()}")
self.logger.info(f"c:{partner_payment_ids.columns}")
temp_table_name = self._create_and_load_table(partner_payment_ids)
table_schema = "partner_staging"
update_query = """UPDATE abc.partner_payment as pp
JOIN partner_staging.{temp_table_name} as t on pp.id =
t.partner_payment_id
SET pp.reconciled = 1, pp.modify_ts = NOW() , pp.modify_user = 'ok
successfull'""""
self.db.execute_insert_update(query_sql=update_query)
self.db.drop_table(table_schema, temp_table_name)
self.logger.info("End reconcile_partner_payments")
def execute_insert_update(self, query_sql, args=()) -> None: #method being used in second_function
try:
cursor = self.get_cursor()
self.start_transaction()
cursor.execute(query_sql, args)
self._connection.handle_unread_result()
self.commit()
except Error as e:
stack = traceback.format_exc()
self.rollback()
print(stack)
logger_func = Cache()[keys.LOGGER].info if keys.LOGGER in Cache() else print
logger_func(f"stack_: {stack}")
raise e
finally:
self.close_cursor()
> def _generate_table_name(self):#generate unique name
self.logger.info("Start _generate_table_name")
rand_str = random_str(length=4)
self.logger.info("End _generate_table_name")
return f"temp_{self.partner_name}_{self.company_name}_{self.payroll_name}_{rand_str}"
i tried defining the schema for the temp table however it is the same error.
英文:
I am working on one personal project.
There is multiple similar questions on this forum however everyone is case specific.
In my case i am creating and loading temp table, i am joining that table with existing table in DB and updating the same table based on temp table results. while executing db.execute_insert_update()
it throws an exception : mysql.connector.errors.DatabaseError: 1412 (HY000): Table definition has changed, please retry transaction
> def _create_and_load_table(self, dataframe: DataFrame) -> str: #first_function
self._log_entry()
temp_table_name = self._generate_table_name()
table_schema = "partner_staging"
table_with_schema = f"{table_schema}.{temp_table_name}"
self.df_mgr.jdbc_write(dataframe=dataframe, dbtable=table_with_schema,
check_count_before_write=True)
self._log_exit()
return temp_table_name
def reconcile_partner_payments(self, dataframe: DataFrame) -> NoReturn: #second function
self.logger.info("Start reconcile_partner_payments")
self.logger.info(f"df_col:{dataframe.columns}")
partner_payment_ids = dataframe.select("partner_payment_id",
"effective_payroll_date").distinct()
self.logger.info(f"head:{partner_payment_ids.head(3)}")
self.logger.info(f"count:{partner_payment_ids.count()}")
self.logger.info(f"c:{partner_payment_ids.columns}")
temp_table_name = self._create_and_load_table(partner_payment_ids)
table_schema = "partner_staging"
update_query = """UPDATE abc.partner_payment as pp
JOIN partner_staging.{temp_table_name} as t on pp.id =
t.partner_payment_id
SET pp.reconciled = 1, pp.modify_ts = NOW() , pp.modify_user = 'ok
successfull'"""
self.db.execute_insert_update(query_sql=update_query)
self.db.drop_table(table_schema, temp_table_name)
self.logger.info("End reconcile_partner_payments")
def execute_insert_update(self, query_sql, args=()) -> None: #method being used in second_function
try:
cursor = self.get_cursor()
self.start_transaction()
cursor.execute(query_sql, args)
self._connection.handle_unread_result()
self.commit()
except Error as e:
stack = traceback.format_exc()
self.rollback()
print(stack)
logger_func = Cache()[keys.LOGGER].info if keys.LOGGER in Cache() else print
logger_func(f"stack_: {stack}")
raise e
finally:
self.close_cursor()
> def _generate_table_name(self):#generate unique name
self.logger.info("Start _generate_table_name")
rand_str = random_str(length=4)
self.logger.info("End _generate_table_name")
return f"temp_{self.partner_name}_{self.company_name}_{self.payroll_name}_{rand_str}"
i tried defining the schema for the temp table however it is the same error.
答案1
得分: 0
以下是已翻译的内容:
看起来你正在同时运行多个实例这个程序,我猜第二个实例开始时创建了一个你认为是临时的表,但实际上是与第一个实例完全相同名称的永久表。第二个程序在第一个程序正在使用表时执行了CREATE TABLE
,导致混淆,DBMS说“我放弃!我不知道你想要什么!”
如何解决这个问题?
-
每次运行程序时生成一个随机或其他唯一的临时表名称,或者...
-
确保你的ORM在创建临时表时使用
CREATE TEMPORARY TABLE tablename
。临时表名称的作用范围既包括连接,也包括模式,因此你可以从不同实例使用相同的名称。
英文:
It looks to my like you're running more than one instance of this program you showed us at once. And, I guess the second instance starts out by creating a table that you think is temporary, but is actually a permanent table with the same exact name as the first instance's. The second program does a CREATE TABLE
while the first one is using the table, and confusion ensues, and the DBMS says "I give up! I don't know what you want!"
How to fix this?
-
Generate a random or otherwise unique name for the temporary table each time you run the program, or ...
-
Make sure your ORM uses
CREATE TEMPORARY TABLE tablename
when it creates that temporary table. Temporary table names are scoped to the connection as well as to the schema, so you can use the same name from different instances.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论