摘要:在数据集成场景中,如无法监控到目标到源表字段发生变动时,会导致数据同步出错。手写一个“源表字段变更检测”的脚本,用于比对源表和目标表字段是否不同,从而及时感知源表字段变动,并相应的按需修改目标表字段结构。
本脚本发布在“华为云Haydn解决方案平台-解决方案加速场-工具&示例代码”。欢迎点击此处加入Haydn~https://haydn.huaweicloud.com/haydnShare/7ac9d6416168a97e/inviteShare/e0a2a7d4dcc8010505dbd1738a96e8b7151bc9ba/0ef13f659ad8441183d0b02154e412af.html
目录
使用场景
脚本使用
1.配置参数
2.连接到一个给定的数据库
3. 获取所有table
4. 获取目标table下的所有column
5. 检测
获取脚本
本脚本为python脚本,用于检测DWS某schema源端目标端字段是否一致。
1、该python脚本依赖PostgreSQL数据库接口psycopg2;
2、通过华为云DGC定时调度该脚本,可联动进行告警通知。
## DWS的用户名
USERNAME = "请输入用户名"
## DWS的密码
PASSWORD = "明文密码"
## DWS的IP地址
HOST = "请输入连接地址"
## DWS的端口
PORT = "8000"
## 该表所在的数据库名称
DATABASE_NAME = "dgc_prod"
## 【修改】贴源层Schema名称
SCHEMA = "sdi_data_frameworkdb"
## 【修改】源数据库系统类型是否为Oracle
SOURCE_DATABASE_IS_ORACLE = False
## 【修改】若源数据库系统类型为Oracle,需要写系统账号名称
SOURCE_DATABASE_USERNAME = 'LCP0019999'
## 若源数据库系统类型不是Oracle,需要写源Schema名称
SOURCE_SCHEMA = SCHEMA[SCHEMA.find('_', 4)+1:]
def connect_to_DWS_and_get_cursor(DATABASE_NAME, USERNAME, PASSWORD, HOST, PORT):
## 连接到一个给定的数据库
conn = psycopg2.connect(database=DATABASE_NAME, user=USERNAME,
password=PASSWORD, host=HOST, port=PORT)
## 使用UTF-8识别中文
conn.set_client_encoding('UTF8')
## 建立游标,用来执行数据库操作
cursor = conn.cursor()
return (conn, cursor)
def get_target_tables_from_schema(cursor, schema):
# 获取目标schema下的所有table
result = []
cursor.execute(
"""
SELECT tablename
FROM pg_tables
WHERE schemaname='{0}';
""".format(schema)
)
rows = cursor.fetchall()
for i in rows:
if i[0] != 'source_columns':
result.append(i[0])
return result
def get_source_columns_from_schema(cursor, schema, table, source_schema, is_oracle, owner):
# 获取源table下的所有column
result = []
rows = []
table = table[4:] if table.startswith("add_") else table
if is_oracle:
cursor.execute(
"""
SELECT DISTINCT column_name, column_id
FROM {0}.source_columns
WHERE lower(table_name) = '{1}'
AND owner = '{2}'
ORDER BY column_id;
""".format(schema, table, owner)
)
rows = cursor.fetchall()
else:
cursor.execute(
"""
SELECT column_name
FROM {0}.source_columns
WHERE table_schema = '{1}'
AND lower(table_name) = '{2}'
ORDER BY ordinal_position;
""".format(schema, source_schema, table)
)
rows = cursor.fetchall()
for i in rows:
result.append(i[0].lower())
return result
def get_target_columns_from_schema(cursor, schema, table):
# 获取目标table下的所有column
result = []
cursor.execute(
"""
SELECT column_name
FROM information_schema.columns
WHERE table_schema = '{0}'
AND table_name = '{1}'
ORDER BY ordinal_position
""".format(schema, table)
)
rows = cursor.fetchall()
for i in rows:
if i[0] != 'data_updated_at' and i[0] != 'data_delete_flag':
result.append(i[0].lower())
return result
def check_two_array_if_same(cursor, target_tables, schema, source_schema, is_oracle, owner):
LOG = ""
error_num = 0
for table in target_tables:
source = get_source_columns_from_schema(cursor, schema, table, source_schema, is_oracle, owner)
target = get_target_columns_from_schema(cursor, schema, table)
if len(source) != len(target):
error_num += 1
LOG += "问题{4}: {0}.{1}表字段数量与源表不一致,源表共{2}个字段,而在DWS中只有{3}个字段。\n".format(schema, table, len(source), len(target), error_num)
continue
diff_cols = ""
for i in range(len(source)):
if source[i] != target[i]:
diff_cols += source[i] + ", "
if diff_cols != "":
error_num += 1
LOG += "问题{3}: {0}.{1}表字段串列或字段错误,与源表不一致:{2}\n".format(schema, table, diff_cols[:-2], error_num)
if LOG != "":
LOG += "\n{0}贴源schema检查完毕,其中共{1}/{2}张表存在问题,请改正。".format(schema, error_num, len(target_tables))
return LOG
本脚本运行在华为云DGC上,用于解决当源表字段发生变动时,CDM集成作业并不会报错的问题,通过比对源表和目标表字段是否不同,从而及时感知源表字段变动,并相应的按需修改目标表字段结构。
本脚本发布在Haydn解决方案数字化平台,完整脚本可在Haydn上获取。
1. 登录服务:使用您的华为云账号登录Haydn解决方案数字化平台,点击【立即使用】-签署服务声明后进入Haydn首页;
2. 查看工具:在Haydn首页点击【解决方案加速场】-【工具&示例代码】,在搜索框中输入“数据使能解决方案实施质量检测工具”即可搜到该工具,点击可进入查看详情&下载代码。