excel-dbapi 0.1.4__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. excel_dbapi-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
  2. excel_dbapi-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +16 -0
  3. excel_dbapi-0.2.0/.github/ISSUE_TEMPLATE/release_checklist.md +23 -0
  4. excel_dbapi-0.2.0/.github/pull_request_template.md +13 -0
  5. excel_dbapi-0.2.0/.github/workflows/ci.yml +36 -0
  6. excel_dbapi-0.2.0/.github/workflows/publish-pypi.yml +28 -0
  7. excel_dbapi-0.2.0/.gitignore +34 -0
  8. excel_dbapi-0.2.0/CHANGELOG.md +18 -0
  9. excel_dbapi-0.2.0/PKG-INFO +280 -0
  10. excel_dbapi-0.2.0/README.md +240 -0
  11. excel_dbapi-0.2.0/docs/DEVELOPMENT.md +80 -0
  12. excel_dbapi-0.2.0/docs/OPERATIONS.md +25 -0
  13. excel_dbapi-0.2.0/docs/PUBLIC_ROADMAP.md +19 -0
  14. excel_dbapi-0.2.0/docs/QUICKSTART_10_MIN.md +36 -0
  15. excel_dbapi-0.2.0/docs/ROADMAP.md +106 -0
  16. excel_dbapi-0.2.0/docs/USAGE.md +118 -0
  17. excel_dbapi-0.2.0/examples/advanced_query.py +17 -0
  18. excel_dbapi-0.2.0/examples/basic_usage.py +15 -0
  19. excel_dbapi-0.2.0/examples/education/lesson_01_first_query.py +8 -0
  20. excel_dbapi-0.2.0/examples/education/lesson_02_parameter_binding.py +7 -0
  21. excel_dbapi-0.2.0/examples/pandas_engine.py +14 -0
  22. excel_dbapi-0.2.0/examples/transactions.py +14 -0
  23. excel_dbapi-0.2.0/examples/write_operations.py +20 -0
  24. excel_dbapi-0.2.0/pyproject.toml +70 -0
  25. excel_dbapi-0.2.0/src/excel_dbapi/__init__.py +78 -0
  26. excel_dbapi-0.2.0/src/excel_dbapi/connection.py +188 -0
  27. excel_dbapi-0.2.0/src/excel_dbapi/cursor.py +149 -0
  28. excel_dbapi-0.2.0/src/excel_dbapi/engines/__init__.py +12 -0
  29. excel_dbapi-0.2.0/src/excel_dbapi/engines/base.py +80 -0
  30. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/__init__.py +5 -0
  31. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/auth.py +132 -0
  32. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/backend.py +380 -0
  33. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/client.py +146 -0
  34. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/locator.py +42 -0
  35. excel_dbapi-0.2.0/src/excel_dbapi/engines/graph/session.py +71 -0
  36. excel_dbapi-0.2.0/src/excel_dbapi/engines/openpyxl/__init__.py +3 -0
  37. excel_dbapi-0.2.0/src/excel_dbapi/engines/openpyxl/backend.py +138 -0
  38. excel_dbapi-0.2.0/src/excel_dbapi/engines/pandas/__init__.py +3 -0
  39. excel_dbapi-0.2.0/src/excel_dbapi/engines/pandas/backend.py +127 -0
  40. excel_dbapi-0.2.0/src/excel_dbapi/engines/registry.py +61 -0
  41. excel_dbapi-0.2.0/src/excel_dbapi/engines/result.py +24 -0
  42. excel_dbapi-0.2.0/src/excel_dbapi/exceptions.py +52 -0
  43. excel_dbapi-0.2.0/src/excel_dbapi/executor.py +363 -0
  44. excel_dbapi-0.2.0/src/excel_dbapi/openpyxl/__init__.py +22 -0
  45. excel_dbapi-0.2.0/src/excel_dbapi/parser.py +521 -0
  46. excel_dbapi-0.2.0/src/excel_dbapi/reflection.py +181 -0
  47. excel_dbapi-0.2.0/src/excel_dbapi/sanitize.py +52 -0
  48. excel_dbapi-0.2.0/tests/data/sample.xlsx +0 -0
  49. excel_dbapi-0.2.0/tests/graph/__init__.py +0 -0
  50. excel_dbapi-0.2.0/tests/graph/test_auth.py +106 -0
  51. excel_dbapi-0.2.0/tests/graph/test_backend.py +764 -0
  52. excel_dbapi-0.2.0/tests/graph/test_client.py +207 -0
  53. excel_dbapi-0.2.0/tests/graph/test_locator.py +46 -0
  54. excel_dbapi-0.2.0/tests/test_additional_coverage.py +70 -0
  55. excel_dbapi-0.2.0/tests/test_api_extensions.py +226 -0
  56. excel_dbapi-0.2.0/tests/test_atomic_rollback_integration.py +52 -0
  57. excel_dbapi-0.2.0/tests/test_base_engine.py +55 -0
  58. excel_dbapi-0.2.0/tests/test_connection.py +26 -0
  59. excel_dbapi-0.2.0/tests/test_connection_graph.py +399 -0
  60. excel_dbapi-0.2.0/tests/test_cursor.py +41 -0
  61. excel_dbapi-0.2.0/tests/test_engine.py +14 -0
  62. excel_dbapi-0.2.0/tests/test_engine_state.py +50 -0
  63. excel_dbapi-0.2.0/tests/test_error_paths.py +94 -0
  64. excel_dbapi-0.2.0/tests/test_exceptions.py +12 -0
  65. excel_dbapi-0.2.0/tests/test_executor.py +21 -0
  66. excel_dbapi-0.2.0/tests/test_formula_injection.py +203 -0
  67. excel_dbapi-0.2.0/tests/test_integration.py +11 -0
  68. excel_dbapi-0.2.0/tests/test_openpyxl_edge_cases.py +18 -0
  69. excel_dbapi-0.2.0/tests/test_openpyxl_facade.py +134 -0
  70. excel_dbapi-0.2.0/tests/test_parser.py +74 -0
  71. excel_dbapi-0.2.0/tests/test_parser_errors.py +58 -0
  72. excel_dbapi-0.2.0/tests/test_pep249_compliance.py +217 -0
  73. excel_dbapi-0.2.0/tests/test_sql_boundaries.py +18 -0
  74. excel_dbapi-0.2.0/tests/test_sql_extensions.py +183 -0
  75. excel_dbapi-0.2.0/tests/test_sql_features.py +133 -0
  76. excel_dbapi-0.2.0/tests/test_stage1_fixes.py +356 -0
  77. excel_dbapi-0.2.0/tests/test_where_operators.py +44 -0
  78. excel_dbapi-0.2.0/tests/test_write_operations.py +175 -0
  79. excel_dbapi-0.1.4/.gitignore +0 -91
  80. excel_dbapi-0.1.4/PKG-INFO +0 -21
  81. excel_dbapi-0.1.4/excel_dbapi/__init__.py +0 -3
  82. excel_dbapi-0.1.4/excel_dbapi/api.py +0 -9
  83. excel_dbapi-0.1.4/excel_dbapi/connection.py +0 -75
  84. excel_dbapi-0.1.4/excel_dbapi/cursor.py +0 -75
  85. excel_dbapi-0.1.4/excel_dbapi/engines/openpyxl_engine.py +0 -46
  86. excel_dbapi-0.1.4/excel_dbapi/exceptions.py +0 -34
  87. excel_dbapi-0.1.4/excel_dbapi/query.py +0 -54
  88. excel_dbapi-0.1.4/excel_dbapi/remote.py +0 -17
  89. excel_dbapi-0.1.4/excel_dbapi/table.py +0 -53
  90. excel_dbapi-0.1.4/pyproject.toml +0 -26
  91. {excel_dbapi-0.1.4 → excel_dbapi-0.2.0}/LICENSE +0 -0
  92. {excel_dbapi-0.1.4/excel_dbapi/engines → excel_dbapi-0.2.0/tests}/__init__.py +0 -0
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a reproducible problem in excel-dbapi
4
+ labels: bug
5
+ ---
6
+
7
+ ## Summary
8
+
9
+ <!-- concise description -->
10
+
11
+ ## Reproduction
12
+
13
+ 1.
14
+ 2.
15
+ 3.
16
+
17
+ ## Expected behavior
18
+
19
+ ## Actual behavior
20
+
21
+ ## Environment
22
+
23
+ - excel-dbapi version:
24
+ - Python version:
25
+ - OS:
26
+ - Engine: openpyxl / pandas
27
+
28
+ ## Sample code / logs
29
+
30
+ ```text
31
+ paste traceback or snippet
32
+ ```
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an enhancement aligned with project boundaries
4
+ labels: enhancement
5
+ ---
6
+
7
+ ## Problem statement
8
+
9
+ ## Proposed solution
10
+
11
+ ## Alternatives considered
12
+
13
+ ## Scope check
14
+
15
+ - [ ] This does not require full SQL-engine behavior (JOIN/GROUP BY/subquery)
16
+ - [ ] This fits DB-API style Excel workflows
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: Release checklist
3
+ about: Track release prep
4
+ labels: release
5
+ ---
6
+
7
+ ## Version
8
+
9
+ - [ ] VERSION updated
10
+ - [ ] pyproject.toml version updated
11
+ - [ ] CHANGELOG updated
12
+ - [ ] Tag planned (`vX.Y.Z`)
13
+
14
+ ## Validation
15
+
16
+ - [ ] CI green
17
+ - [ ] Coverage artifact generated (`coverage.xml`)
18
+ - [ ] `python -m build` passes
19
+
20
+ ## Publish
21
+
22
+ - [ ] Trusted Publishing environment configured
23
+ - [ ] Release notes drafted
@@ -0,0 +1,13 @@
1
+ ## Summary
2
+
3
+ ## Related issue
4
+
5
+ Fixes #
6
+
7
+ ## Checklist
8
+
9
+ - [ ] Focused change (no unrelated refactor)
10
+ - [ ] Tests added/updated
11
+ - [ ] Docs updated if behavior changed
12
+ - [ ] `pytest` passes locally
13
+ - [ ] Boundary maintained (not expanding to full SQL engine)
@@ -0,0 +1,36 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - name: Install dependencies
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install -e ".[dev,pandas]"
23
+ - name: Run tests with coverage
24
+ run: pytest tests/ -v --cov=excel_dbapi --cov-report=xml --cov-report=term-missing
25
+ - name: Upload coverage to Codecov
26
+ if: matrix.python-version == '3.12'
27
+ uses: codecov/codecov-action@v5
28
+ with:
29
+ files: coverage.xml
30
+ fail_ci_if_error: false
31
+ - name: Run ruff
32
+ run: ruff check src/
33
+ - name: Run ruff format check
34
+ run: ruff format --check src/
35
+ - name: Run mypy strict
36
+ run: mypy --strict src/
@@ -0,0 +1,28 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment: pypi
11
+ permissions:
12
+ id-token: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Install build tools
22
+ run: pip install build
23
+
24
+ - name: Build package
25
+ run: python -m build
26
+
27
+ - name: Publish to PyPI
28
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,34 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.py[cod]
5
+ *.so
6
+
7
+ # Virtual environments
8
+ .venv/
9
+ venv/
10
+ env/
11
+
12
+ # Tool caches
13
+ .pytest_cache/
14
+ .mypy_cache/
15
+ .ruff_cache/
16
+ .coverage
17
+ coverage.xml
18
+ htmlcov/
19
+
20
+ # Build artifacts
21
+ build/
22
+ dist/
23
+ *.egg-info/
24
+
25
+ # Data files
26
+ *.xlsx
27
+ !tests/data/*.xlsx
28
+
29
+ # IDE
30
+ .vscode/
31
+ .idea/
32
+
33
+ # OS
34
+ .DS_Store
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.1.0] - 2026-04-12
6
+
7
+ ### Added
8
+ - PEP 249 (DB-API 2.0) compliant driver for Excel files
9
+ - SQL support: SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, DROP TABLE
10
+ - WHERE clauses with AND/OR, comparison operators, LIKE, IN, IS NULL/IS NOT NULL
11
+ - ORDER BY and LIMIT for SELECT queries
12
+ - Openpyxl engine (default) for local .xlsx files
13
+ - Pandas engine (optional) for DataFrame-based operations
14
+ - Microsoft Graph API engine (optional) for remote Excel files
15
+ - Formula injection defense (enabled by default)
16
+ - Transaction simulation (commit/rollback)
17
+ - Reflection helpers for dialect integration
18
+ - Metadata sheet support for schema persistence
@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.4
2
+ Name: excel-dbapi
3
+ Version: 0.2.0
4
+ Summary: PEP 249 compliant DB-API driver for Excel files
5
+ Project-URL: Homepage, https://github.com/yeongseon/excel-dbapi
6
+ Project-URL: Repository, https://github.com/yeongseon/excel-dbapi
7
+ Project-URL: Issues, https://github.com/yeongseon/excel-dbapi/issues
8
+ Project-URL: Changelog, https://github.com/yeongseon/excel-dbapi/blob/main/CHANGELOG.md
9
+ Author-email: Yeongseon Choe <yeongseon.choe@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: db-api,excel,openpyxl,pandas,sql
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Database
23
+ Classifier: Topic :: Software Development :: Libraries
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: openpyxl<4.0.0,>=3.1.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: httpx>=0.27; extra == 'dev'
28
+ Requires-Dist: mypy>=1.10; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.4; extra == 'dev'
32
+ Provides-Extra: graph
33
+ Requires-Dist: httpx>=0.27; extra == 'graph'
34
+ Provides-Extra: graph-azure
35
+ Requires-Dist: azure-identity>=1.15; extra == 'graph-azure'
36
+ Requires-Dist: httpx>=0.27; extra == 'graph-azure'
37
+ Provides-Extra: pandas
38
+ Requires-Dist: pandas<3.0.0,>=2.0.0; extra == 'pandas'
39
+ Description-Content-Type: text/markdown
40
+
41
+
42
+ # excel-dbapi
43
+
44
+ ![CI](https://github.com/yeongseon/excel-dbapi/actions/workflows/ci.yml/badge.svg)
45
+ [![codecov](https://codecov.io/gh/yeongseon/excel-dbapi/branch/main/graph/badge.svg)](https://codecov.io/gh/yeongseon/excel-dbapi)
46
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
48
+
49
+ A lightweight, Python DB-API 2.0 compliant connector for Excel files.
50
+ Use SQL to query, insert, update, and delete rows in `.xlsx` workbooks — no database server required.
51
+
52
+ ## Who is this for?
53
+
54
+ - **Data analysts** who want to query Excel files with SQL instead of manual filtering
55
+ - **Citizen developers** automating small workflows with familiar SQL syntax
56
+ - **Educators** teaching SQL concepts without setting up a database
57
+ - **Prototypers** building quick data pipelines before moving to a real database
58
+
59
+ ### Who is this NOT for?
60
+
61
+ - If you need JOINs, GROUP BY, subqueries, or advanced SQL → use SQLite or PostgreSQL
62
+ - If you need concurrent writes from multiple processes → use a real database
63
+ - If your Excel file has 100k+ rows → use pandas directly or a database
64
+
65
+ ---
66
+
67
+ ## Features
68
+
69
+ - Python DB-API 2.0 compliant interface (PEP 249)
70
+ - Query Excel files using SQL syntax
71
+ - Supports SELECT, INSERT, UPDATE, DELETE
72
+ - Basic DDL support (CREATE TABLE, DROP TABLE)
73
+ - WHERE conditions with AND/OR and comparison operators
74
+ - ORDER BY and LIMIT for SELECT
75
+ - Sheet-to-Table mapping
76
+ - Pandas & Openpyxl engine selector
77
+ - Formula injection defense (enabled by default)
78
+ - Transaction simulation (commit/rollback)
79
+
80
+ ---
81
+
82
+ ## Installation
83
+
84
+ ```bash
85
+ pip install excel-dbapi
86
+ ```
87
+
88
+ See [CHANGELOG](CHANGELOG.md) for release history.
89
+
90
+ ---
91
+
92
+ ## Quick Start
93
+
94
+ ```python
95
+ from excel_dbapi.connection import ExcelConnection
96
+
97
+ # Open an Excel file and query it
98
+ with ExcelConnection("sample.xlsx") as conn:
99
+ cursor = conn.cursor()
100
+ cursor.execute("SELECT * FROM Sheet1")
101
+ print(cursor.fetchall())
102
+ ```
103
+
104
+ ### Insert, Update, Delete
105
+
106
+ ```python
107
+ with ExcelConnection("sample.xlsx") as conn:
108
+ cursor = conn.cursor()
109
+
110
+ # Insert with parameter binding (recommended)
111
+ cursor.execute("INSERT INTO Sheet1 (id, name) VALUES (?, ?)", (1, "Alice"))
112
+
113
+ # Update
114
+ cursor.execute("UPDATE Sheet1 SET name = 'Ann' WHERE id = 1")
115
+
116
+ # Delete
117
+ cursor.execute("DELETE FROM Sheet1 WHERE id = 2")
118
+ ```
119
+
120
+ ### Create and Drop Sheets
121
+
122
+ ```python
123
+ with ExcelConnection("sample.xlsx") as conn:
124
+ cursor = conn.cursor()
125
+ cursor.execute("CREATE TABLE NewSheet (id, name)")
126
+ cursor.execute("DROP TABLE NewSheet")
127
+ ```
128
+
129
+ ### Engine Options
130
+
131
+ | Engine | Description | Dependency |
132
+ |--------|-------------|------------|
133
+ | openpyxl (default) | Fast sheet access | openpyxl |
134
+ | pandas | DataFrame-based operations | pandas, openpyxl |
135
+
136
+ ```python
137
+ conn = ExcelConnection("sample.xlsx", engine="openpyxl") # default
138
+ conn = ExcelConnection("sample.xlsx", engine="pandas")
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Safety Defaults
144
+
145
+ ### Formula Injection Defense
146
+
147
+ By default, `excel-dbapi` sanitizes cell values on write (INSERT/UPDATE) to prevent
148
+ [formula injection attacks](https://owasp.org/www-community/attacks/CSV_Injection).
149
+ Strings starting with `=`, `+`, `-`, `@`, `\t`, or `\r` are automatically prefixed
150
+ with a single quote (`'`) so they are stored as plain text, not executed as formulas.
151
+
152
+ ```python
153
+ # Default: sanitization ON (recommended)
154
+ with ExcelConnection("sample.xlsx") as conn:
155
+ cursor = conn.cursor()
156
+ cursor.execute("INSERT INTO Sheet1 (id, name) VALUES (?, ?)",
157
+ (1, "=SUM(A1:A10)"))
158
+ # Stored as: '=SUM(A1:A10) (safe, not executed as formula)
159
+
160
+ # Opt out if you intentionally write formulas
161
+ with ExcelConnection("sample.xlsx", sanitize_formulas=False) as conn:
162
+ cursor = conn.cursor()
163
+ cursor.execute("INSERT INTO Sheet1 (id, formula) VALUES (?, ?)",
164
+ (1, "=SUM(A1:A10)"))
165
+ # Stored as: =SUM(A1:A10) (executed as formula in Excel)
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Transaction Example
171
+
172
+ ```python
173
+ with ExcelConnection("sample.xlsx", autocommit=False) as conn:
174
+ cursor = conn.cursor()
175
+ cursor.execute("UPDATE Sheet1 SET name = 'Ann' WHERE id = 1")
176
+ conn.rollback()
177
+ ```
178
+
179
+ When autocommit is enabled, `rollback()` is not supported.
180
+
181
+ ## Cursor Metadata
182
+
183
+ ```python
184
+ with ExcelConnection("sample.xlsx") as conn:
185
+ cursor = conn.cursor()
186
+ cursor.execute("SELECT id, name FROM Sheet1")
187
+ print(cursor.description)
188
+ print(cursor.rowcount)
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Troubleshooting
194
+
195
+ ### "Column 'xyz' not found"
196
+
197
+ The column name in your SQL doesn't match any header in the sheet.
198
+
199
+ ```
200
+ ProgrammingError: Column 'nmae' not found in Sheet1. Available columns: ['id', 'name', 'email']
201
+ ```
202
+
203
+ **Fix:** Check the spelling. Column names must match the first row (header) of the sheet exactly.
204
+
205
+ ### "Table 'SheetX' not found"
206
+
207
+ The sheet name in your SQL doesn't match any sheet in the workbook.
208
+
209
+ ```
210
+ ProgrammingError: Table 'Shee1' not found. Available sheets: ['Sheet1', 'Sheet2']
211
+ ```
212
+
213
+ **Fix:** Check the sheet name spelling. Use the exact sheet name (case-sensitive) shown in your Excel file.
214
+
215
+ ### PandasEngine drops formatting
216
+
217
+ `PandasEngine` reads data into a DataFrame and writes it back. This process drops
218
+ Excel formatting, charts, images, and formulas.
219
+
220
+ **Fix:** Use the default `openpyxl` engine if you need to preserve formatting.
221
+
222
+ ### Integer vs. string comparison (Pandas)
223
+
224
+ The Pandas engine preserves Python types. If a column contains integers,
225
+ `WHERE id = '2'` (string) won't match — use `WHERE id = 2` (no quotes).
226
+
227
+ **Fix:** Omit quotes around numeric values in WHERE clauses when using the Pandas engine.
228
+
229
+ ---
230
+
231
+ ## Limitations and Operational Guidance
232
+
233
+ - `PandasEngine` rewrites workbooks and may drop formatting, charts, and formulas.
234
+ - `OpenpyxlEngine` loads with `data_only=True`, so formulas are evaluated to values when reading.
235
+ - Use a **single-writer model** for writes. Avoid writing to the same file from multiple processes.
236
+ - Save is implemented with a temporary file + atomic replace (`os.replace`) for safer persistence.
237
+ - No support for JOIN, GROUP BY, HAVING, or subqueries.
238
+
239
+ ## Roadmap
240
+
241
+ - Remote file connection improvements
242
+
243
+ See [Project Roadmap](docs/ROADMAP.md) for details.
244
+
245
+ ---
246
+
247
+
248
+ ## Related Projects
249
+
250
+ ### sqlalchemy-excel
251
+
252
+ [sqlalchemy-excel](https://github.com/yeongseon/sqlalchemy-excel) is a higher-level toolkit that uses excel-dbapi as its core Excel I/O layer. It provides SQLAlchemy model-driven template generation, server-side validation, database import, and export.
253
+
254
+ - **Which package should I use?** See the [decision guide](https://github.com/yeongseon/sqlalchemy-excel/blob/main/docs/which-package.md)
255
+ - **Interface contract**: See the [compatibility documentation](https://github.com/yeongseon/sqlalchemy-excel/blob/main/docs/compatibility.md)
256
+
257
+ ---
258
+
259
+ ## Documentation
260
+
261
+ - [Usage Guide](docs/USAGE.md)
262
+ - [Development Guide](docs/DEVELOPMENT.md)
263
+ - [Project Roadmap](docs/ROADMAP.md)
264
+ - [10-Minute Quickstart](docs/QUICKSTART_10_MIN.md)
265
+ - [Operations Notes](docs/OPERATIONS.md)
266
+ - [Public Roadmap](docs/PUBLIC_ROADMAP.md)
267
+
268
+ ## Examples
269
+
270
+ - `examples/basic_usage.py`
271
+ - `examples/write_operations.py`
272
+ - `examples/transactions.py`
273
+ - `examples/advanced_query.py`
274
+ - `examples/pandas_engine.py`
275
+
276
+ ---
277
+
278
+ ## License
279
+
280
+ MIT License