Metadata-Version: 2.4
Name: teradata-latin
Version: 0.1.0
Summary: Teradata LATIN character set codec: recover GBK-encoded Chinese stored in LATIN columns, and encode Chinese for SQL literals (teradatasql UTF-8 session compatible)
Author: wuyichen
License: MIT
Project-URL: Homepage, https://github.com/yujchn/teradata-latin
Keywords: teradata,latin,gbk,charset,encoding,chinese
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# teradata-latin

Teradata LATIN 字符集中文编解码组件（纯标准库，零依赖）。

## 问题背景

Teradata 的 `LATIN` 字符集列中常见以 GBK 编码存储的中文（历史 ETL 通过
`CLIENT_CHARSET=GBK` 的 JDBC 会话直通写入）。使用官方纯 Python 驱动
[teradatasql](https://pypi.org/project/teradatasql/)（固定 UTF-8 会话、
不支持 charset 参数）读取时，服务端按 Teradata LATIN 代码页逐字节映射
Unicode，落在 `0x80-0x9F` / `0xD0-0xFE` 等区间的 GBK 字节会被映射为不同
码位（如 `0xD0 -> U+00F0`、`0xDE -> U+00FE`、`0xD7 -> U+0152`、
`0xF7 -> U+0153`、`0xB8 -> U+0160`），中文变成乱码。

`tdlatin` 提供与生产 JDBC（`CHARSET=GBK`）等价的转换：

- **读取方向**：乱码字符 -> 原始字节（Teradata LATIN 映射）-> GBK 解码 = 正确中文
- **写入/过滤方向**：正确中文 -> GBK 字节 -> Teradata LATIN 映射字符，
  嵌入 SQL 字面量后由服务端 `UNICODE_TO_LATIN` 转回原始字节，比较语义与生产一致

## 安装

```bash
pip install teradata-latin
```

## 用法

```python
import teradatasql
from teradata_latin import decode_td_latin, encode_td_latin

con = teradatasql.connect(host='...', user='...', password='...')

# 1) 读出中文列 -> 还原
cur = con.cursor()
cur.execute("SELECT TOP 5 Client_CN_Name FROM pv_pmart.DIM_CLIENT_BASE_INFO")
for (name,) in cur.fetchall():
    print(decode_td_latin(name))   # '上海玛仕特国际货运代理有限公司'

# 2) SQL 中文字面量 / 中文参数 -> 编码后嵌入
lit = encode_td_latin('0未逾期')
cur.execute("SELECT count(1) FROM t WHERE AR_Overdue_Mth IN ('%s','')" % lit)

name = encode_td_latin('昆山千友工业环保设备有限公司')
cur.execute("SELECT Client_id FROM t WHERE Client_CN_Name = '%s'" % name)
```

## API

| 函数 | 说明 |
|---|---|
| `decode_td_latin(text, errors='replace')` | 读出乱码 -> 正确中文；无法映射时安全原样返回（或 `errors='strict'` 抛错） |
| `encode_td_latin(text, errors='strict')` | 中文 -> SQL 字面量；GBK 不可编码字符可 `errors='replace'` |
| `TDLatinCoder` | 面向对象封装（`decode` / `encode`） |

映射表可通过 `TDBYTE_TO_UNICODE` / `UNICODE_TO_TDBYTE` / `DRIFT_BYTE_COUNT`
访问（196 个实测字节，18 个与标准 Latin-1 不一致）。

## 映射表来源

多张线上业务表（订单/客户/财务/营收/逾期）共 9000+ 行采样 + Teradata
`UNICODE_TO_LATIN` / `LATIN_TO_UNICODE` 服务端往返实验验证，确定性一一映射，
无冲突；漂移字节全部通过服务端往返校验。

## License

MIT
