Metadata-Version: 2.4
Name: sqlServerConnector
Version: 0.1.24
Summary: A custom SQL Server Connector for ETL processes with Pandas
Author-email: Nguyen Minh Son <nguyen.minhson1511@gmail.com>
Project-URL: Homepage, https://github.com/johnnyb1509/sqlServerConnector
Keywords: sql,etl,pandas,sqlalchemy
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: pandas>=1.5.0
Requires-Dist: numpy
Requires-Dist: sqlalchemy>=2.0.0
Requires-Dist: pyodbc
Requires-Dist: pyyaml
Requires-Dist: loguru
Requires-Dist: jupyterlab

# SQL Server Connector

Thư viện kết nối SQL Server chuyên dụng cho các tác vụ ETL, được tối ưu hóa cho **Pandas**, hỗ trợ **Tiếng Việt (Unicode)** và **Upsert (Merge)** hiệu năng cao.

### **Update 0.1.24**
- **Về mặt Logic (Coverage):** Toàn bộ các "tuyệt chiêu" bạn đã viết như conflict_strategy (sum, last, skip), auto_evolve_schema (tự động thêm cột), hay tự động dò Data Type (_generate_dtype_mapping) đều được giữ nguyên vẹn 100%.

- **Về mặt Transaction (Giao dịch):** Ở phiên bản cũ, bạn gộp toàn bộ quá trình: Tạo bảng -> Thêm cột -> Tạo bảng Staging -> Đổ data -> Chạy lệnh MERGE vào chung một giao dịch duy nhất (with self.engine.begin()). Việc này rủi ro ở chỗ: nếu quá trình dài bị đứt kết nối giữa chừng, hoặc thư viện Pandas ngầm commit, toàn bộ sẽ bị kẹt hoặc rollback trong im lặng.

- **Ở phiên bản mới:** Chúng ta chuyển sang mô hình Micro-transactions (Giao dịch chia nhỏ) dùng engine.connect() và ép conn.commit() cho từng chặng. Điều này tương thích hoàn hảo với sự khắt khe của SQLAlchemy 2.0+, giúp đảm bảo lệnh nào chạy xong là "chốt sổ" lệnh đó, bất chấp bạn dùng driver pyodbc hay pymssql.

## 🚀 Tính năng nổi bật

* **High Performance:** Sử dụng `fast_executemany` giúp insert dữ liệu nhanh gấp 10-50 lần so với thông thường.
* **Smart Upsert:** Tự động chèn mới (Insert) hoặc cập nhật (Update) dựa trên Khóa chính (Primary Key).
* **Schema Evolution:** Tự động tạo bảng nếu chưa có, tự động thêm cột mới (Add Column) nếu DataFrame có thay đổi.
* **Unicode Support:** Xử lý triệt để lỗi font chữ Tiếng Việt khi làm việc với SQL Server & Pandas.
* **SQLAlchemy 2.0:** Tuân thủ chuẩn kết nối hiện đại, an toàn.

---
## 📦 Cài đặt

### Cách 1: Cài đặt trực tiếp từ Git (Khuyên dùng nội bộ)
Dành cho đồng nghiệp trong team, cài đặt không cần file whl.

```bash
# Cài phiên bản mới nhất từ nhánh main

pip install git+https://github.com/johnnyb1509/sqlServerConnector.git
```

### Cách 2: Cài đặt từ file .whl
Dành cho người dùng cuối, cài đặt từ file whl đã build sẵn.

```bash
pip install sqlServerConnector
```


## Cấu hình kết nối Database
File cấu hình `db_config.yaml`

```yaml
# Thông tin kết nối Database
# Lưu ý: Đảm bảo máy tính đã cài đặt ODBC Driver 17 for SQL Server
db_info:
    server: "localhost"  # Ví dụ: localhost hoặc  
    database: "YOUR_DATABASE_NAME"    # Ví dụ: TestDB
    username: "YOUR_USERNAME"         # Ví dụ: sa
    password: "YOUR_PASSWORD"         # Mật khẩu
```

## 📝 Hướng dẫn sử dụng nhanh

1. Khởi tạo kết nối
```python
import yaml
from connector import SQLServerConnector

# Load config
with open('config/db_config.yaml', 'r') as f:
    conf = yaml.safe_load(f)['db_info']

# Khởi tạo
db = SQLServerConnector(
    server=conf['server'],
    database=conf['database'],
    username=conf['username'],
    password=conf['password']
)
```

2. Lấy dữ liệu (Read)
```python
# Cách 1: Lấy toàn bộ bảng
df = db.get_data("SELECT * FROM DM_KhachHang")

# Cách 2: Dùng câu lệnh SQL tuy bien
query = """
    SELECT TOP 100 * FROM Sales_Transaction
    WHERE created_date >= :from_date
"""
df_sales = db.get_data(query, params={"from_date": "2023-01-01"})
print(df_sales.head())
```

3. Kiểm tra bảng tồn tại
```python
if not db.check_table_exists("Fact_Sales"):
    print("Bang Fact_Sales chua ton tai")
```

4. Ghi du lieu (Upsert)
```python
import pandas as pd

# Gia lap du lieu
data = {
    'TransactionID': [101, 102],
    'Product': ['Laptop Dell', 'Chuot Logitech'],  # Ho tro tieng Viet
    'Amount': [15000000, 250000]
}
df_new = pd.DataFrame(data)

# Day vao DB
db.upsert_data(
    df=df_new,
    target_table="Fact_Sales",
    match_columns=["TransactionID"],  # Khoa so khop (Primary Key)
    conflict_strategy="last",         # "last" hoac "skip"
    auto_evolve_schema=True            # Tu dong them cot neu thieu
)
print("Du lieu da duoc upsert thanh cong!")
```

5. Thuc thi cau lenh khong tra ve du lieu
```python
# Vi du: xoa du lieu cu
db.execute_query(
    "DELETE FROM Fact_Sales WHERE created_date < :cutoff",
    params={"cutoff": "2023-01-01"}
)
```

6. Dong ket noi
```python
# Luon dong ket noi khi hoan tat de giai phong tai nguyen
db.dispose()
```

## ⚠️ Lưu ý quan trọng
1. **Primary Key:** Khi dùng upsert_data, bat buoc phai cung cap `match_columns`. Neu bang chua co Primary Key, thu vien se co gang set cac cot nay lam khoa chinh khi tao bang moi.

2. **Date Time:** Các cột ngày tháng nên được convert sang datetime64[ns] trong Pandas trước khi đẩy vào để đảm bảo tính chính xác.

3. **Upgrade version:** Luôn kiểm tra và cập nhật lên phiên bản mới nhất để tận dụng các tính năng và sửa lỗi mới nhất. For developer, change version in `pyproject.toml` and build & upload to PyPI:   
```bash
python -m build
python -m twine upload dist/*
```
