Skip to content

Commit

Permalink
oracle-DDL备份原始定义
Browse files Browse the repository at this point in the history
  • Loading branch information
unknowissue committed Jan 14, 2022
1 parent fea32d2 commit d77a9fc
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions sql/engines/oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,17 @@ def execute_workflow(self, workflow, close_conn=True):
statement = sqlitem.statement
if sqlitem.stmt_type == "SQL":
statement = statement.rstrip(';')
#如果是DDL的工单,获取对象的原定义,并保存到sql_rollback.undo_sql
#需要授权 grant execute on dbms_metadata to xxxxx
if workflow.syntax_type == 1:
object_name=self.get_sql_first_object_name(statement)
back_obj_sql=f"""select dbms_metadata.get_ddl(object_type,object_name,owner)
from all_objects where (object_name=upper( '{object_name}' ) or OBJECT_NAME = '{sqlitem.object_name}')
and owner='{workflow.db_name}'
"""
cursor.execute(back_obj_sql)
metdata_back_flag=self.metdata_backup(workflow, cursor,statement)

with FuncTimer() as t:
if statement != '':
cursor.execute(statement)
Expand Down Expand Up @@ -773,6 +784,48 @@ def backup(self, workflow, cursor, begin_time, end_time):
conn.close()
return True

def metdata_backup(self, workflow, cursor ,redo_sql):
"""
:param workflow: 工单对象,作为备份记录与工单的关联列
:param cursor: 执行SQL的当前会话游标,保存metadata
:param redo_sql: 执行的SQL
:return:
"""
try:
# 备份存放数据库和MySQL备份库统一,需新建备份用database和table,table存放备份SQL,记录使用workflow.id关联上线工单
workflow_id = workflow.id
conn = self.get_backup_connection()
backup_cursor = conn.cursor()
backup_cursor.execute(f"""create database if not exists ora_backup;""")
backup_cursor.execute(f"use ora_backup;")
backup_cursor.execute(f"""CREATE TABLE if not exists `sql_rollback` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`redo_sql` mediumtext,
`undo_sql` mediumtext,
`workflow_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
key `idx_sql_rollback_01` (`workflow_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;""")
rows = cursor.fetchall()
if len(rows) > 0:
for row in rows:
if row[0] is None:
undo_sql = f' '
else:
undo_sql = f"{row[0]}"
undo_sql = undo_sql.replace("'", "\\'")
# 回滚SQL入库
sql = f"""insert into sql_rollback(redo_sql,undo_sql,workflow_id) values('{redo_sql}','{undo_sql}',{workflow_id});"""
backup_cursor.execute(sql)
except Exception as e:
logger.warning(f"备份失败,错误信息{traceback.format_exc()}")
return False
finally:
# 关闭连接
if conn:
conn.close()
return True

def get_rollback(self, workflow):
"""
add by Jan.song 20200402
Expand Down

0 comments on commit d77a9fc

Please sign in to comment.