如何检测某schema源端目标端字段是否一致

摘要:在数据集成场景中,如无法监控到目标到源表字段发生变动时,会导致数据同步出错。手写一个“源表字段变更检测”的脚本,用于比对源表和目标表字段是否不同,从而及时感知源表字段变动,并相应的按需修改目标表字段结构。

本脚本发布在“华为云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定时调度该脚本,可联动进行告警通知。

如何检测某schema源端目标端字段是否一致_第1张图片

脚本使用

1.配置参数

## 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:]

2.连接到一个给定的数据库

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)

3. 获取所有table

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

 4. 获取目标table下的所有column

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

5. 检测

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首页点击【解决方案加速场】-【工具&示例代码】,在搜索框中输入“数据使能解决方案实施质量检测工具”即可搜到该工具,点击可进入查看详情&下载代码。

你可能感兴趣的:(工具&示例代码,数据库,数据仓库)