sqlServerConnector 0.1.11
A custom SQL Server Connector for ETL processes with Pandas
Requires Python: >=3.8
Keywords: sql, etl, pandas, sqlalchemy

# 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.9**
> Thay vì dùng bảng tạm (##Staging), sẽ dùng bảng vật lý tạm thời (Physical Staging Table) có tên chứa UUID (để đảm bảo duy nhất, không trùng lặp giữa các luồng chạy). Sau khi Upsert xong, ta sẽ DROP bảng này ngay lập tức. Cách này tương thích 100% với Pandas và SQLAlchemy.

### **Update 0.1.7**
> Sửa lỗi nhỏ liên quan đến việc upsert với các bảng có cột chứa Tiếng Việt


## 🚀 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/*
```