|
20 | 20 | 5-1. 샘플 문서 자동 생성 |
21 | 21 | 6. 가장 쉬운 로컬 스모크 테스트 (API 키 없이) |
22 | 22 | 7. BaselineNL2SQL 기본 사용 (KeywordRetriever) |
| 23 | +7-1. DB 탐색: SQLAlchemyExplorer |
23 | 24 | 8. 실제 LLM 연결 (OpenAI / Anthropic) |
24 | 25 | 9. VectorRetriever 기초 (빠른 시작) |
25 | 26 | 10. 문서 파싱: MarkdownLoader / PlainTextLoader / DirectoryLoader / PDFLoader |
@@ -232,6 +233,99 @@ print(rows) |
232 | 233 |
|
233 | 234 | --- |
234 | 235 |
|
| 236 | +## 7-1) DB 탐색: SQLAlchemyExplorer |
| 237 | + |
| 238 | +LLM에게 넘길 스키마 정보가 필요하거나, 처음 보는 DB를 손으로 살펴볼 때 사용합니다. |
| 239 | +카탈로그를 미리 구축하지 않아도 DDL + 샘플 데이터를 바로 꺼내볼 수 있습니다. |
| 240 | + |
| 241 | +### 기본 사용 |
| 242 | + |
| 243 | +```python |
| 244 | +from lang2sql import build_explorer_from_url |
| 245 | + |
| 246 | +exp = build_explorer_from_url("sqlite:///sample.db") |
| 247 | + |
| 248 | +# 1) 어떤 테이블이 있는지 |
| 249 | +print(exp.list_tables()) |
| 250 | +# ['customers', 'orders', ...] |
| 251 | + |
| 252 | +# 2) 테이블 DDL — CREATE TABLE 원문 |
| 253 | +print(exp.get_ddl("orders")) |
| 254 | +# CREATE TABLE orders ( |
| 255 | +# id INTEGER PRIMARY KEY, |
| 256 | +# customer_id INTEGER NOT NULL REFERENCES customers(id), |
| 257 | +# amount REAL, |
| 258 | +# status TEXT DEFAULT 'pending' |
| 259 | +# ) |
| 260 | + |
| 261 | +# 3) 실제 샘플 데이터 (기본 5행) |
| 262 | +print(exp.sample_data("orders")) |
| 263 | +# [{'id': 1, 'customer_id': 1, 'amount': 99.9, 'status': 'shipped'}, ...] |
| 264 | + |
| 265 | +# 4) 커스텀 읽기 전용 질의 |
| 266 | +print(exp.execute_read_only("SELECT status, COUNT(*) AS cnt FROM orders GROUP BY status")) |
| 267 | +# [{'status': 'pending', 'cnt': 3}, {'status': 'shipped', 'cnt': 2}] |
| 268 | +``` |
| 269 | + |
| 270 | +### 전체 테이블 한 번에 둘러보기 |
| 271 | + |
| 272 | +```python |
| 273 | +from lang2sql import build_explorer_from_url |
| 274 | + |
| 275 | +exp = build_explorer_from_url("sqlite:///sample.db") |
| 276 | + |
| 277 | +for table in exp.list_tables(): |
| 278 | + print(f"\n=== {table} ===") |
| 279 | + print(exp.get_ddl(table)) |
| 280 | + rows = exp.sample_data(table, limit=2) |
| 281 | + print("샘플:", rows) |
| 282 | +``` |
| 283 | + |
| 284 | +### PostgreSQL / MySQL 연결 |
| 285 | + |
| 286 | +URL만 바꾸면 됩니다. |
| 287 | + |
| 288 | +```python |
| 289 | +from lang2sql import build_explorer_from_url |
| 290 | + |
| 291 | +# PostgreSQL |
| 292 | +exp = build_explorer_from_url("postgresql://user:password@localhost:5432/mydb") |
| 293 | + |
| 294 | +# MySQL |
| 295 | +exp = build_explorer_from_url("mysql+pymysql://user:password@localhost:3306/mydb") |
| 296 | + |
| 297 | +# schema 지정 (schema 파라미터) |
| 298 | +exp = build_explorer_from_url("postgresql://user:pass@host/db", schema="analytics") |
| 299 | +print(exp.list_tables()) # analytics 스키마 테이블만 |
| 300 | +``` |
| 301 | + |
| 302 | +### 기존 SQLAlchemyDB engine 재사용 |
| 303 | + |
| 304 | +연결 풀을 따로 만들지 않고 공유할 수 있습니다. |
| 305 | + |
| 306 | +```python |
| 307 | +from lang2sql.integrations.db import SQLAlchemyDB, SQLAlchemyExplorer |
| 308 | + |
| 309 | +db = SQLAlchemyDB("sqlite:///sample.db") |
| 310 | +exp = SQLAlchemyExplorer.from_engine(db._engine) |
| 311 | + |
| 312 | +# db는 SQL 실행, exp는 탐색 — 같은 연결 풀 공유 |
| 313 | +rows = db.execute("SELECT COUNT(*) AS cnt FROM orders") |
| 314 | +ddl = exp.get_ddl("orders") |
| 315 | +``` |
| 316 | + |
| 317 | +### 쓰기 구문은 거부됩니다 |
| 318 | + |
| 319 | +```python |
| 320 | +exp.execute_read_only("DROP TABLE orders") |
| 321 | +# ValueError: Write operations not allowed: 'DROP TABLE orders' |
| 322 | + |
| 323 | +exp.execute_read_only("INSERT INTO orders VALUES (99, 1, 0, 'test')") |
| 324 | +# ValueError: Write operations not allowed: 'INSERT INTO orders ...' |
| 325 | +``` |
| 326 | + |
| 327 | +--- |
| 328 | + |
235 | 329 | ## 8) 실제 LLM 연결 (OpenAI / Anthropic) |
236 | 330 |
|
237 | 331 | LLM 백엔드는 교체 가능합니다. |
|
0 commit comments