Skip to content

Commit 3773e92

Browse files
DOC: Fix factual errors and remove slop from LLM guidance files
- Remove nonexistent prompt file references (#setup-dev-env, #build-ddbc, etc.) - Remove duplicated usage examples section from copilot-instructions.md - Fix C++ style: Google -> LLVM (verified against .clang-format) - Update pybind file tree to match actual directory contents (14 items) - Add 3 missing GitHub workflows (lint-check, pr-code-coverage, forked-pr-coverage) - Remove pip install black (already in requirements.txt) - Remove Trust These Instructions section - Remove platform-specific ODBC install section from llms.txt (bundled via pip) - Fix undefined user_id variable in Quick Start example - Fix except Exception -> except DatabaseError with proper import - Remove unused Error import from error handling example - Remove redundant code comments and trivial Access Columns by Index section - Fix pyodbc comparison table for accuracy (pooling, Entra ID claims) - Clarify OUTPUT params use DECLARE/EXEC/SELECT workaround (callproc() unsupported) - Remove unverified performance claim from connection pooling - Fix SUSE platform listing: x64 only per wiki, separate from ARM64 platforms
1 parent 3f81374 commit 3773e92

2 files changed

Lines changed: 38 additions & 171 deletions

File tree

.github/copilot-instructions.md

Lines changed: 24 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,92 +12,13 @@
1212

1313
## Development Workflows
1414

15-
This repository includes detailed prompt files for common tasks. Reference these with `#`:
16-
17-
| Task | Prompt | When to Use |
18-
|------|--------|-------------|
19-
| First-time setup | `#setup-dev-env` | New machine, fresh clone |
20-
| Build C++ extension | `#build-ddbc` | After modifying .cpp/.h files |
21-
| Run tests | `#run-tests` | Validating changes |
22-
| Create PR | `#create-pr` | Ready to submit changes |
23-
2415
**Workflow order for new contributors:**
25-
1. `#setup-dev-env` → Set up venv and dependencies
26-
2. `#build-ddbc` → Build native extension
27-
3. Make your changes
28-
4. `#run-tests` → Validate
29-
5. `#create-pr` → Submit
30-
31-
## Usage Examples (For Suggesting to Users)
32-
33-
> **Security Note**: Examples use `TrustServerCertificate=yes` for local development with self-signed certificates. For production, remove this option to ensure proper TLS certificate validation.
34-
35-
### Basic Connection and Query
36-
```python
37-
import mssql_python
38-
39-
conn = mssql_python.connect(
40-
"SERVER=localhost;DATABASE=mydb;Trusted_Connection=yes;Encrypt=yes;TrustServerCertificate=yes"
41-
)
42-
cursor = conn.cursor()
43-
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
44-
rows = cursor.fetchall()
45-
cursor.close()
46-
conn.close()
47-
```
48-
49-
### Context Manager (Recommended)
50-
```python
51-
with mssql_python.connect(connection_string) as conn:
52-
with conn.cursor() as cursor:
53-
cursor.execute("SELECT @@VERSION")
54-
print(cursor.fetchone()[0])
55-
```
56-
57-
### Azure SQL with Entra ID
58-
```python
59-
conn = mssql_python.connect(
60-
"SERVER=myserver.database.windows.net;DATABASE=mydb;"
61-
"Authentication=ActiveDirectoryInteractive;Encrypt=yes"
62-
)
63-
```
64-
65-
### Parameterized Queries
66-
```python
67-
# Positional parameters
68-
cursor.execute("SELECT * FROM users WHERE email = ?", (email,))
69-
70-
# Named parameters (pyformat)
71-
cursor.execute("SELECT * FROM users WHERE email = %(email)s", {"email": email})
72-
```
73-
74-
### Insert with Commit
75-
```python
76-
cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ("John", "john@example.com"))
77-
conn.commit()
78-
```
79-
80-
### Batch Insert
81-
```python
82-
cursor.executemany("INSERT INTO users (name, email) VALUES (?, ?)", [
83-
("Alice", "alice@example.com"),
84-
("Bob", "bob@example.com"),
85-
])
86-
conn.commit()
87-
```
88-
89-
### Transaction Handling
90-
```python
91-
from mssql_python import DatabaseError
92-
93-
try:
94-
cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE id = ?", (from_id,))
95-
cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE id = ?", (to_id,))
96-
conn.commit()
97-
except DatabaseError:
98-
conn.rollback()
99-
raise
100-
```
16+
1. Create and activate a virtual environment (`python -m venv .venv`)
17+
2. Install dependencies (`pip install -r requirements.txt`)
18+
3. Build the native extension (see Build System below)
19+
4. Make your changes
20+
5. Run tests (`python -m pytest -v`)
21+
6. Submit a PR
10122

10223
## Build System and Validation
10324

@@ -155,7 +76,6 @@ python -m pytest tests/test_001_globals.py -v # Basic functionality
15576

15677
```bash
15778
# Python formatting
158-
pip install black
15979
black --check --line-length=100 mssql_python/ tests/
16080

16181
# C++ formatting
@@ -188,11 +108,18 @@ mssql_python/
188108
├── helpers.py # Utility functions and settings
189109
├── ddbc_bindings.py # Platform-specific extension loader with architecture detection
190110
├── mssql_python.pyi # Type stubs for IDE support
111+
├── py.typed # PEP 561 type marker
191112
└── pybind/ # Native extension source
192113
├── ddbc_bindings.cpp # Main C++ binding code
114+
├── ddbc_bindings.h # Header for bindings
193115
├── CMakeLists.txt # Cross-platform build configuration
194116
├── build.sh/.bat # Platform-specific build scripts
195-
└── configure_dylibs.sh # macOS dylib configuration
117+
├── configure_dylibs.sh # macOS dylib configuration
118+
├── logger_bridge.cpp/.hpp # Python logging bridge
119+
├── unix_utils.cpp/.h # Unix platform utilities
120+
└── connection/ # Connection management
121+
├── connection.cpp/.h # Connection implementation
122+
└── connection_pool.cpp/.h # Connection pooling
196123
```
197124

198125
### Platform-Specific Libraries
@@ -206,9 +133,9 @@ mssql_python/libs/
206133

207134
### Configuration Files
208135

209-
- **`.clang-format`**: C++ formatting (Google style, 100 column limit)
210-
- **`.coveragerc`**: Coverage exclusions (main.py, setup.py, tests/)
211-
- **`requirements.txt`**: Development dependencies (pytest, pybind11, coverage)
136+
- **`.clang-format`**: C++ formatting (LLVM style, 100 column limit)
137+
- **`.coveragerc`**: Coverage configuration
138+
- **`requirements.txt`**: Development dependencies
212139
- **`setup.py`**: Package configuration with platform detection
213140
- **`pyproject.toml`**: Modern Python packaging configuration
214141
- **`.gitignore`**: Excludes build artifacts (*.so, *.pyd, build/, __pycache__)
@@ -218,6 +145,9 @@ mssql_python/libs/
218145
### GitHub Workflows
219146
- **`devskim.yml`**: Security scanning (runs on PRs and main)
220147
- **`pr-format-check.yml`**: PR validation (title format, GitHub issue/ADO work item links)
148+
- **`lint-check.yml`**: Python (Black) and C++ (clang-format) linting
149+
- **`pr-code-coverage.yml`**: Code coverage reporting
150+
- **`forked-pr-coverage.yml`**: Coverage for forked PRs
221151

222152
### Azure DevOps Pipelines (`eng/pipelines/`)
223153
- **`pr-validation-pipeline.yml`**: Comprehensive testing across all platforms
@@ -253,7 +183,7 @@ The CI system tests:
253183

254184
## Architecture Detection and Loading
255185

256-
The `ddbc_bindings.py` module implements sophisticated architecture detection:
186+
The `ddbc_bindings.py` module handles architecture detection:
257187
- **Windows**: Normalizes `win64/amd64/x64``x64`, `win32/x86``x86`, `arm64``arm64`
258188
- **macOS**: Runtime architecture detection, always loads from universal2 binary
259189
- **Linux**: Maps `x64/amd64``x86_64`, `arm64/aarch64``arm64`
@@ -298,17 +228,17 @@ Exception (base)
298228
- Follow RAII patterns for resource management
299229
- Use `py::gil_scoped_release` for blocking ODBC operations
300230
- Update `mssql_python.pyi` type stubs if changing Python API
301-
- Follow `.clang-format` style (Google style, 100 column limit)
231+
- Follow `.clang-format` style (LLVM style, 100 column limit)
302232

303233
## Debugging Quick Reference
304234

305235
| Error | Cause | Solution |
306236
|-------|-------|----------|
307-
| `ImportError: ddbc_bindings` | Extension not built | Run `#build-ddbc` |
237+
| `ImportError: ddbc_bindings` | Extension not built | Build native extension (see Build System) |
308238
| Connection timeout | Missing env var | Set `DB_CONNECTION_STRING` |
309239
| `dylib not found` (macOS) | Library paths | Run `configure_dylibs.sh` |
310240
| `ODBC Driver not found` | Missing driver | Install Microsoft ODBC Driver 18 |
311-
| `ModuleNotFoundError` | Not in venv | Run `#setup-dev-env` |
241+
| `ModuleNotFoundError` | Not in venv | Activate virtual environment |
312242

313243
## Contributing Guidelines
314244

@@ -323,11 +253,3 @@ Exception (base)
323253
3. **Test on target platform** before submitting PRs
324254
4. **Check CI pipeline results** for cross-platform compatibility
325255

326-
## Trust These Instructions
327-
328-
These instructions are comprehensive and tested. Only search for additional information if:
329-
- Build commands fail with unexpected errors
330-
- New platform support is being added
331-
- Dependencies or requirements have changed
332-
333-
For any ambiguity, refer to the platform-specific README in `mssql_python/pybind/README.md` or the comprehensive CI pipeline configurations in `eng/pipelines/`.

llms.txt

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# mssql-python
22

3-
> Microsoft Python Driver for SQL Server and Azure SQL
4-
53
mssql-python is the official Microsoft Python driver for SQL Server and Azure SQL databases. It provides DB API 2.0 compliant database access with Direct Database Connectivity (DDBC) - no external ODBC driver manager required.
64

75
## Installation
@@ -15,59 +13,19 @@ Or using uv (recommended for faster installs):
1513
uv pip install mssql-python
1614
```
1715

18-
### Platform-Specific Dependencies
19-
20-
**macOS** - Install the ODBC driver:
21-
```bash
22-
brew install msodbcsql18
23-
```
24-
25-
**Debian/Ubuntu**:
26-
```bash
27-
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
28-
curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
29-
sudo apt-get update
30-
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
31-
```
32-
33-
**RHEL/CentOS/Fedora**:
34-
```bash
35-
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
36-
curl https://packages.microsoft.com/config/rhel/$(rpm -E %rhel)/prod.repo | sudo tee /etc/yum.repos.d/mssql-release.repo
37-
sudo ACCEPT_EULA=Y yum install -y msodbcsql18
38-
```
39-
40-
**Alpine Linux**:
41-
```bash
42-
apk add --no-cache curl gnupg
43-
curl -O https://download.microsoft.com/download/1/f/f/1fffeb70-cd3d-42d5-a7ee-b75c4ff5fb9e/msodbcsql18_18.4.1.1-1_amd64.apk
44-
apk add --allow-untrusted msodbcsql18_18.4.1.1-1_amd64.apk
45-
```
46-
47-
**SUSE Linux**:
48-
```bash
49-
sudo zypper addrepo https://packages.microsoft.com/config/sles/15/prod.repo
50-
sudo ACCEPT_EULA=Y zypper install -y msodbcsql18
51-
```
52-
5316
## Quick Start
5417

5518
> **Security Note**: The examples below use `TrustServerCertificate=yes` for local development with self-signed certificates. For production or remote connections, remove this option to ensure proper TLS certificate validation.
5619

5720
```python
5821
import mssql_python
5922

60-
# Connect to SQL Server
6123
conn = mssql_python.connect(
6224
"SERVER=localhost;DATABASE=mydb;Trusted_Connection=yes;Encrypt=yes;TrustServerCertificate=yes"
6325
)
6426
cursor = conn.cursor()
65-
66-
# Execute a query
67-
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
27+
cursor.execute("SELECT * FROM users WHERE id = ?", (42,))
6828
rows = cursor.fetchall()
69-
70-
# Always close when done
7129
cursor.close()
7230
conn.close()
7331
```
@@ -116,7 +74,6 @@ conn = mssql_python.connect(
11674
```python
11775
import mssql_python
11876

119-
# Connection and cursor automatically close on exit
12077
with mssql_python.connect(connection_string) as conn:
12178
with conn.cursor() as cursor:
12279
cursor.execute("SELECT @@VERSION")
@@ -128,22 +85,16 @@ with mssql_python.connect(connection_string) as conn:
12885

12986
### Parameterized Queries (Prevent SQL Injection)
13087
```python
131-
# Use ? placeholders for parameters
13288
cursor.execute("SELECT * FROM users WHERE email = ? AND active = ?", (email, True))
13389

134-
# Or use named parameters with pyformat style
90+
# Named parameters (pyformat style)
13591
cursor.execute("SELECT * FROM users WHERE email = %(email)s", {"email": email})
13692
```
13793

13894
### Fetch Results
13995
```python
140-
# Fetch one row
14196
row = cursor.fetchone()
142-
143-
# Fetch multiple rows
14497
rows = cursor.fetchmany(size=100)
145-
146-
# Fetch all remaining rows
14798
all_rows = cursor.fetchall()
14899
```
149100

@@ -183,11 +134,13 @@ conn.commit()
183134
## Transaction Management
184135

185136
```python
137+
from mssql_python import DatabaseError
138+
186139
try:
187140
cursor.execute("INSERT INTO orders (customer_id, total) VALUES (?, ?)", (1, 99.99))
188141
cursor.execute("UPDATE inventory SET quantity = quantity - 1 WHERE product_id = ?", (42,))
189142
conn.commit() # Commit both changes
190-
except Exception as e:
143+
except DatabaseError:
191144
conn.rollback() # Rollback on error
192145
raise
193146
```
@@ -200,15 +153,6 @@ conn.autocommit = True # Each statement commits immediately
200153

201154
## Working with Results
202155

203-
### Access Columns by Index
204-
```python
205-
cursor.execute("SELECT id, name, email FROM users")
206-
for row in cursor.fetchall():
207-
user_id = row[0]
208-
name = row[1]
209-
email = row[2]
210-
```
211-
212156
### Get Column Metadata
213157
```python
214158
cursor.execute("SELECT id, name, email FROM users")
@@ -223,7 +167,8 @@ for column in cursor.description:
223167
cursor.execute("EXEC GetUserById ?", (user_id,))
224168
result = cursor.fetchone()
225169

226-
# Stored procedure with output
170+
# OUTPUT parameters: use DECLARE/EXEC/SELECT pattern
171+
# (callproc() is not supported; use execute() with anonymous code blocks)
227172
cursor.execute("""
228173
DECLARE @count INT;
229174
EXEC CountActiveUsers @count OUTPUT;
@@ -236,7 +181,6 @@ count = cursor.fetchone()[0]
236181

237182
```python
238183
from mssql_python import (
239-
Error,
240184
DatabaseError,
241185
IntegrityError,
242186
ProgrammingError,
@@ -262,7 +206,7 @@ except DatabaseError as e:
262206

263207
## Connection Pooling
264208

265-
Connection pooling is enabled by default for improved performance:
209+
Connection pooling is enabled by default:
266210

267211
```python
268212
# Pooling is automatic - connections are reused
@@ -276,10 +220,10 @@ conn2 = mssql_python.connect(connection_string) # Reuses pooled connection
276220

277221
| Feature | mssql-python | pyodbc |
278222
|---------|-------------|--------|
279-
| Driver Manager | Built-in (DDBC) | Requires ODBC |
280-
| Installation | `pip install` only | Requires ODBC setup |
281-
| Azure Entra ID | Native support | Requires extra config |
282-
| Connection Pooling | Built-in | Manual |
223+
| Driver | Ships bundled | Requires separate ODBC driver |
224+
| Installation | `pip install` only | pip install + ODBC driver setup |
225+
| Azure Entra ID | Native Python API | Via ODBC driver connection keywords |
226+
| Connection Pooling | Built-in | Via ODBC Driver Manager |
283227
| DB API 2.0 | ✅ Compliant | ✅ Compliant |
284228

285229
### Migration from pyodbc
@@ -297,7 +241,8 @@ conn = mssql_python.connect("SERVER=...;DATABASE=...")
297241

298242
- Windows (x64, ARM64)
299243
- macOS (ARM64, x86_64)
300-
- Linux (x86_64, ARM64): Debian, Ubuntu, RHEL, SUSE, Alpine (musl)
244+
- Linux (x86_64, ARM64): Debian, Ubuntu, RHEL, Alpine (musl)
245+
- Linux (x86_64 only): SUSE
301246

302247
## Supported Python Versions
303248

0 commit comments

Comments
 (0)