运维联盟俱乐部

 找回密码
 立即注册
查看: 205|回复: 1

godba

[复制链接]
  • TA的每日心情
    开心
    2023-8-9 11:05
  • 发表于 2024-1-12 22:42:49 | 显示全部楼层 |阅读模式



    这是一个Python脚本,使用cx_Oracle模块连接Oracle数据库,并从一个数据库中的表获取连接信息,然后遍历这些连接信息并连接到对应的数据库,查询其中的用户信息,最后将查询结果插入到另一个数据库中的表中。该脚本的作用是将多个Oracle数据库的用户信息收集到一个统一的库中,方便管理和监控。

    具体来说,该脚本会执行以下步骤:

    使用cx_Oracle模块连接到一个Oracle数据库,从其中的godba_add_db表获取多个目标数据库的连接信息,包括IP地址、监听端口、服务名、用户名、密码和数据库UUID等。

    遍历连接信息,对于每个目标数据库,使用cx_Oracle模块连接到该数据库,查询其中的dba_users表,获取其中的用户信息,包括用户名、用户ID、密码、账号状态、锁定时间、过期时间、默认表空间、临时表空间、本地临时表空间、创建时间、配置文件、初始资源消费者组、外部名称、密码版本、启用版本、身份验证类型、仅代理连接、常用设置、上次登录、Oracle维护、继承、默认排序规则、隐式用户、全局分片、密码更改时间和检查时间等。

    将查询结果插入到另一个Oracle数据库的godba_users表中,也包括上述所有字段,以及db_uuid字段,用于标识该用户信息所属的数据库。

    关闭游标和连接,并提交事务。

    1. import cx_Oracle

    2. #从rep库获取数据库连接信息
    3. target_conn = cx_Oracle.connect("zhyu/zhyu@192.168.56.101:1521/ora19")
    4. target_cursor = target_conn.cursor()
    5. dbl_query = "SELECT IP_ADDRESS, LISTENER_PORT, SERVICE_NAME, USERNAME, PASSWORD, DB_UUID FROM godba_add_db"
    6. target_cursor.execute(dbl_query)
    7. #遍历连接信息,从源库查询信息并存放到rep库
    8. for IP_ADDRESS, LISTENER_PORT, SERVICE_NAME, USERNAME, PASSWORD, DB_UUID in target_cursor.fetchall():
    9.   source_conn = cx_Oracle.connect(f"{USERNAME}/{PASSWORD}@{IP_ADDRESS}:{LISTENER_PORT}/{SERVICE_NAME}")
    10.   source_cursor = source_conn.cursor()
    11.   source_cursor.execute("SELECT username,user_id,password,account_status,lock_date,expiry_date,default_tablespace,temporary_tablespace,local_temp_tablespace,created,profile,INITIAL_RSRC_CONSUMER_GROUP,EXTERNAL_NAME,PASSWORD_VERSIONS,EDITIONS_ENABLED,AUTHENTICATION_TYPE,PROXY_ONLY_CONNECT,COMMON,LAST_LOGIN,ORACLE_MAINTAINED,INHERITED,DEFAULT_COLLATION,IMPLICIT,ALL_SHARD,PASSWORD_CHANGE_DATE,to_char(sysdate,'yyyymmddhh24miss') check_time FROM dba_users")
    12.   for result in source_cursor.fetchall():
    13.     target_cursor.execute("INSERT INTO godba_users (username,user_id,password,account_status,lock_date,expiry_date,default_tablespace,temporary_tablespace,local_temp_tablespace,created,profile,INITIAL_RSRC_CONSUMER_GROUP,EXTERNAL_NAME,PASSWORD_VERSIONS,EDITIONS_ENABLED,AUTHENTICATION_TYPE,PROXY_ONLY_CONNECT,COMMON,LAST_LOGIN,ORACLE_MAINTAINED,INHERITED,DEFAULT_COLLATION,IMPLICIT,ALL_SHARD,PASSWORD_CHANGE_DATE,check_time,db_uuid) VALUES (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27)", result + (DB_UUID,))
    14. #关闭游标,关闭连接
    15.   source_cursor.close()
    16.   source_conn.close()
    17.   target_conn.commit()
    18.   target_cursor.close()
    19.   target_conn.close()
    复制代码


    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-8-9 11:05
  •  楼主| 发表于 2024-1-12 22:45:45 | 显示全部楼层
    1. import cx_Oracle
    2. import logging
    3. import time

    4. # 配置日志记录器
    5. logger = logging.getLogger(__name__)
    6. logger.setLevel(logging.INFO)
    7. handler = logging.FileHandler("database.log")
    8. handler.setLevel(logging.INFO)
    9. formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
    10. handler.setFormatter(formatter)
    11. logger.addHandler(handler)

    12. # 从rep库获取数据库连接信息
    13. target_conn = cx_Oracle.connect("zhyu/zhyu@192.168.56.101:1521/ora19")
    14. target_cursor = target_conn.cursor()
    15. dbl_query = "SELECT IP_ADDRESS, LISTENER_PORT, SERVICE_NAME, USERNAME, PASSWORD, DB_UUID FROM godba_add_db"
    16. target_cursor.execute(dbl_query)

    17. # 遍历连接信息,从源库查询信息并存放到rep库
    18. for IP_ADDRESS, LISTENER_PORT, SERVICE_NAME, USERNAME, PASSWORD, DB_UUID in target_cursor.fetchall():
    19.     retry_count = 0
    20.     while retry_count < 3:
    21.         try:
    22.             logger.info(f"Connecting to {IP_ADDRESS}:{LISTENER_PORT}/{SERVICE_NAME}...")
    23.             source_conn = cx_Oracle.connect(
    24.                 f"{USERNAME}/{PASSWORD}@{IP_ADDRESS}:{LISTENER_PORT}/{SERVICE_NAME}")
    25.             source_cursor = source_conn.cursor()
    26.             source_cursor.execute(
    27.                 "SELECT username,user_id,password,account_status,lock_date,expiry_date,default_tablespace,temporary_tablespace,local_temp_tablespace,created,profile,INITIAL_RSRC_CONSUMER_GROUP,EXTERNAL_NAME,PASSWORD_VERSIONS,EDITIONS_ENABLED,AUTHENTICATION_TYPE,PROXY_ONLY_CONNECT,COMMON,LAST_LOGIN,ORACLE_MAINTAINED,INHERITED,DEFAULT_COLLATION,IMPLICIT,ALL_SHARD,PASSWORD_CHANGE_DATE,to_char(sysdate,'yyyymmddhh24miss') check_time FROM dba_users")
    28.             for result in source_cursor.fetchall():
    29.                 target_cursor.execute("INSERT INTO godba_users (username,user_id,password,account_status,lock_date,expiry_date,default_tablespace,temporary_tablespace,local_temp_tablespace,created,profile,INITIAL_RSRC_CONSUMER_GROUP,EXTERNAL_NAME,PASSWORD_VERSIONS,EDITIONS_ENABLED,AUTHENTICATION_TYPE,PROXY_ONLY_CONNECT,COMMON,LAST_LOGIN,ORACLE_MAINTAINED,INHERITED,DEFAULT_COLLATION,IMPLICIT,ALL_SHARD,PASSWORD_CHANGE_DATE,check_time,db_uuid) VALUES (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27)",
    30.                                       result + (DB_UUID,))
    31.             logger.info(f"Successfully processed {IP_ADDRESS}:{LISTENER_PORT}/{SERVICE_NAME}.")
    32.             break
    33.         except cx_Oracle.DatabaseError as e:
    34.             logger.error(f"Unable to connect to {IP_ADDRESS}:{LISTENER_PORT}/{SERVICE_NAME}. Retry count: {retry_count+1}", exc_info=True)
    35.             if retry_count == 2:
    36.                 logger.error(f"Connection failed after 3 retries. Skipping to the next database.")
    37.             else:
    38.                 retry_count += 1
    39.                 time.sleep(5)  # Wait for 5 seconds before retrying

    40.     # 关闭游标,关闭连接
    41.     source_cursor.close()
    42.     source_conn.close()

    43. target_conn.commit()
    44. target_cursor.close()
    45. target_conn.close()
    复制代码


    在上述代码中,我们使用了try-except块来捕获cx_Oracle.DatabaseError异常,该异常表示数据库连接失败。如果连接失败,将打印错误消息,并在重试次数小于3时进行重试。如果连续尝试3次都无法连接成功,则跳过当前数据库,继续下一个数据库的处理。
    请注意,我在连接失败后添加了一个5秒的延迟,以避免频繁尝试连接导致过多的资源消耗。你可以根据实际情况调整这个延迟时间。
    另外,我还将提交事务的操作移动到了循环外部,在处理完所有数据库后进行提交,以提高效率。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    运维联盟俱乐部 ( 冀ICP备19036648号 )

    GMT+8, 2024-5-2 17:30 , Processed in 0.052407 second(s), 21 queries , Gzip On.

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表