UI は翻訳済み。スキル原文は作者の言語を維持し、一部の説明は英語です。
スキルを探す
データ・研究 · SKILL.md

python-enterprise-connectors

python-enterprise-connectors

Use when connecting Python to enterprise databases (DB2, Oracle, SQL Server, Teradata), mainframe systems (z/OS, CICS, IMS, MQ), or building custom database connectors. Covers ibm_db, Zowe SDK, pyodbc, python-oracledb, EBCDIC handling, credential management, and connection security.

Independent GitHub snapshot · Automated classification · Original documentation governs

スキルの説明

GitHub

name: python-enterprise-connectors description: Use when connecting Python to enterprise databases (DB2, Oracle, SQL Server, Teradata), mainframe systems (z/OS, CICS, IMS, MQ), or building custom database connectors. Covers ibm_db, Zowe SDK, pyodbc, python-oracledb, EBCDIC handling, credential management, and connection security. family: python

Python Enterprise Connectors

Overview

Enterprise database and mainframe connectivity in Python requires specific drivers, careful credential management, and understanding of legacy data formats. This skill covers DB2, Oracle, SQL Server, mainframe systems, and patterns for building robust connectors with proper security.

IBM DB2

Drivers

DriverUse CaseStatus (2026)
ibm_db (v3.2.3)Direct DB2 access via CLI/ODBCActive, Python 3.9-3.14
ibm_db_saSQLAlchemy dialect for DB2Active, supports SA 2.0
ibm_db_dbiDB-API 2.0 interfacePart of ibm_db package
pyodbc + DB2 ODBCAlternative via ODBC driverWorks but less feature-rich
jaydebeapi + JDBCJVM-based alternativeRequires JRE

Connection Patterns

import ibm_db

# DB2 LUW (Linux/Unix/Windows)
conn = ibm_db.connect(
    f"DATABASE={db};HOSTNAME={host};PORT={port};PROTOCOL=TCPIP;UID={user};PWD={pwd};SECURITY=SSL;",
    "", ""
)

# DB2 z/OS (mainframe) — REQUIRES DB2 Connect license
conn = ibm_db.connect(
    f"DATABASE={location};HOSTNAME={host};PORT={port};PROTOCOL=TCPIP;UID={user};PWD={pwd};",
    "", ""
)

Critical gotcha: DB2 z/OS connections require a paid DB2 Connect license. Without it: SQL1598N error. This is the #1 issue developers hit.

Performance Tuning

# Increase fetch size for large result sets
stmt = ibm_db.exec_immediate(conn, sql)
ibm_db.set_option(stmt, {ibm_db.SQL_ATTR_CURSOR_TYPE: ibm_db.SQL_CURSOR_FORWARD_ONLY}, 1)
# Use array fetch for bulk operations

EBCDIC Handling

Mainframe DB2 (z/OS) uses EBCDIC encoding. Known issues with ibm_db error message decoding.

# Convert EBCDIC to UTF-8
data.decode('cp500').encode('utf-8')  # CP500 = common EBCDIC code page
# Or use codecs
import codecs
text = codecs.decode(ebcdic_bytes, 'cp037')  # CP037 = US EBCDIC

Common EBCDIC code pages: CP037 (US/Canada), CP500 (International), CP1047 (z/OS Unix).

Mainframe Connectivity

Zowe Python SDK (Modern Approach)

pip install zowe-zos-files-for-zowe-sdk zowe-zos-jobs-for-zowe-sdk zowe-zos-tso-for-zowe-sdk
PackageCapability
zowe-zos-filesRead/write MVS datasets, USS files
zowe-zos-jobsSubmit JCL, monitor job status, retrieve output
zowe-zos-tsoExecute TSO commands
zowe-zos-consoleIssue console commands

Status (2026): Pre-release (v1.0.0.dev25) but actively developed. For production, consider Zowe CLI with subprocess calls as a more stable alternative.

z/OSMF REST API (Direct)

import httpx

client = httpx.Client(base_url="https://mainframe:443/zosmf", verify=True,
                      auth=(user, password))

# List datasets
response = client.get("/restfiles/ds", params={"dslevel": "USER.PROD.*"})

# Submit JCL
response = client.put("/restjobs/jobs",
    content=jcl_content,
    headers={"Content-Type": "text/plain"})
job_id = response.json()["jobid"]

# Check job status
response = client.get(f"/restjobs/jobs/{job_name}/{job_id}")

Terminal Emulation (3270)

LibraryStatusNotes
IBM tnzRecommendedPure Python, no external emulator, battle-tested inside IBM
py3270ActiveRequires x3270/s3270 installed
x3270 via subprocessWorksShell out to x3270 binary

IBM MQ (Messaging)

# Package renamed: pymqi → ibmmq (v2.0.3, Feb 2026)
import ibmmq

qmgr = ibmmq.connect(queue_manager)
queue = ibmmq.Queue(qmgr, 'QUEUE.NAME')
queue.put('message data')
message = queue.get()
queue.close()
qmgr.disconnect()

z/OS Connect (REST → CICS/IMS)

z/OS Connect 3.0 provides RESTful access to CICS transactions and IMS programs. This is the recommended path for Python-to-CICS/IMS since CTG has no native Python client.

# Call a CICS transaction via z/OS Connect
response = httpx.post(
    "https://zosconnect:9443/zosConnect/apis/myApi/operation",
    json={"input_field": "value"},
    auth=(user, password)
)

Other Enterprise Databases

DatabaseDriverKey Notes
Oraclepython-oracledb (replaces cx_Oracle)Thin mode = no Oracle Client dependency. Migration: keyword-only params breaking change
SQL Servermssql-python (GA Nov 2025)New first-party driver, 40% faster than pyodbc, no dependencies
SQL Server (legacy)pyodbcStill works, wider compatibility
TeradatateradatasqlOfficial driver + SQLAlchemy dialect
SAP HANAhdbcliOfficial SAP driver
Snowflakesnowflake-connector-pythonOfficial, includes pandas integration
BigQuerygoogle-cloud-bigqueryService account auth, magics for notebooks

Deprecated — Migrate Away

OldNewDeadline
cx_Oraclepython-oracledbcx_Oracle in maintenance only
pymqiibmmq (v2.0+)pymqi still works but renamed
Motor (MongoDB async)PyMongo native asyncMotor EOL May 2026
aioredisredis.asyncio (redis-py v4.2+)aioredis merged

Connector Building Patterns

DB-API 2.0 Compliance

All Python database drivers should implement PEP 249:

  • connect() → connection object
  • connection.cursor() → cursor object
  • cursor.execute(sql, params) → parameterized queries
  • cursor.fetchone(), fetchmany(), fetchall()
  • connection.commit(), connection.rollback()

Connection Factory

class DatabaseConnector:
    def __init__(self, config: dict):
        self.config = config
        self._engine = None

    def get_engine(self):
        if self._engine is None:
            self._engine = create_engine(
                self.config['url'],
                pool_size=self.config.get('pool_size', 10),
                pool_pre_ping=True,
                pool_recycle=300,
            )
        return self._engine

    def health_check(self) -> bool:
        try:
            with self.get_engine().connect() as conn:
                conn.execute(text("SELECT 1"))
            return True
        except Exception:
            return False

Retry Pattern

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=30),
    retry=retry_if_exception_type((ConnectionError, TimeoutError)),
)
def execute_query(engine, sql, params):
    with engine.connect() as conn:
        return conn.execute(text(sql), params)

Credential Security

Hierarchy (Best → Worst)

  1. HashiCorp Vault dynamic secrets (auto-rotating, short-lived)
  2. Cloud secret managers (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager)
  3. Environment variables (acceptable for simple deployments)
  4. Config files (encrypted, not in git)
  5. Hardcoded in code — NEVER
# Vault dynamic secrets (hvac library)
import hvac
client = hvac.Client(url='https://vault:8200', token=os.environ['VAULT_TOKEN'])
creds = client.secrets.database.generate_credentials('my-role')
username, password = creds['data']['username'], creds['data']['password']
# Credentials auto-expire after TTL

Connection String Safety

# NEVER log connection strings with passwords
import re
def sanitize_url(url: str) -> str:
    return re.sub(r'://[^:]+:[^@]+@', '://***:***@', url)

Data Type Gotchas

IssueDatabasesSolution
Decimal precision lossAllUse decimal.Decimal, never float for money
Timezone-naive datetimesMySQL, older PostgresAlways store UTC, use datetime.timezone.utc
EBCDIC encodingDB2 z/OSDecode with cp037/cp500/cp1047
Packed decimal (COMP-3)MainframeCustom unpacking or struct module
NULL vs empty stringOracle (treats '' as NULL)Handle in application logic
BLOB/CLOB streamingOracle, DB2Use LOB locators, don't fetch full object to memory

Anti-Patterns

Don'tWhy
Hardcode credentials in codeExposed in version control — use vault or env vars
Disable TLS verification (verify=False)MITM vulnerability — always verify in production
Use float for financial dataPrecision loss — use decimal.Decimal
Create connections per requestPerformance killer — use connection pooling
Assume same SQL works across databasesDialects differ — test per database or use ORM
Use cx_Oracle for new projectsDeprecated — use python-oracledb
Skip DB2 Connect license check for z/OSSQL1598N at runtime — verify license first
Log connection strings with passwordsCredential leak — sanitize before logging
Use pickle for data transfer between systemsSecurity risk — use JSON/Protocol Buffers
保存したスキル