sqldoc 1.3.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 (39) hide show
  1. sqldoc-1.3.0/PKG-INFO +325 -0
  2. sqldoc-1.3.0/README.md +299 -0
  3. sqldoc-1.3.0/pyproject.toml +44 -0
  4. sqldoc-1.3.0/setup.cfg +4 -0
  5. sqldoc-1.3.0/sqldoc/__init__.py +1 -0
  6. sqldoc-1.3.0/sqldoc/ai.py +311 -0
  7. sqldoc-1.3.0/sqldoc/cli.py +828 -0
  8. sqldoc-1.3.0/sqldoc/extractor.py +428 -0
  9. sqldoc-1.3.0/sqldoc/health.py +273 -0
  10. sqldoc-1.3.0/sqldoc/health_renderer.py +197 -0
  11. sqldoc-1.3.0/sqldoc/intel.py +332 -0
  12. sqldoc-1.3.0/sqldoc/intel_renderer.py +172 -0
  13. sqldoc-1.3.0/sqldoc/json_renderer.py +45 -0
  14. sqldoc-1.3.0/sqldoc/markdown_renderer.py +214 -0
  15. sqldoc-1.3.0/sqldoc/pdf_renderer.py +243 -0
  16. sqldoc-1.3.0/sqldoc/pii.py +418 -0
  17. sqldoc-1.3.0/sqldoc/pii_renderer.py +201 -0
  18. sqldoc-1.3.0/sqldoc/quality.py +210 -0
  19. sqldoc-1.3.0/sqldoc/quality_renderer.py +196 -0
  20. sqldoc-1.3.0/sqldoc/renderer.py +974 -0
  21. sqldoc-1.3.0/sqldoc/sarif.py +86 -0
  22. sqldoc-1.3.0/sqldoc/snapshot.py +227 -0
  23. sqldoc-1.3.0/sqldoc.egg-info/PKG-INFO +325 -0
  24. sqldoc-1.3.0/sqldoc.egg-info/SOURCES.txt +37 -0
  25. sqldoc-1.3.0/sqldoc.egg-info/dependency_links.txt +1 -0
  26. sqldoc-1.3.0/sqldoc.egg-info/entry_points.txt +2 -0
  27. sqldoc-1.3.0/sqldoc.egg-info/requires.txt +12 -0
  28. sqldoc-1.3.0/sqldoc.egg-info/top_level.txt +1 -0
  29. sqldoc-1.3.0/tests/test_ai.py +125 -0
  30. sqldoc-1.3.0/tests/test_cli.py +292 -0
  31. sqldoc-1.3.0/tests/test_extractor.py +80 -0
  32. sqldoc-1.3.0/tests/test_health.py +92 -0
  33. sqldoc-1.3.0/tests/test_intel.py +138 -0
  34. sqldoc-1.3.0/tests/test_json_renderer.py +50 -0
  35. sqldoc-1.3.0/tests/test_pii.py +182 -0
  36. sqldoc-1.3.0/tests/test_quality.py +91 -0
  37. sqldoc-1.3.0/tests/test_renderers.py +104 -0
  38. sqldoc-1.3.0/tests/test_sarif.py +46 -0
  39. sqldoc-1.3.0/tests/test_snapshot.py +85 -0
sqldoc-1.3.0/PKG-INFO ADDED
@@ -0,0 +1,325 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqldoc
3
+ Version: 1.3.0
4
+ Summary: SQL Server database documentation generator + PII/compliance scanner, with optional AI-written descriptions.
5
+ Author: htamber
6
+ Project-URL: Homepage, https://github.com/htamber1/sqldoc
7
+ Project-URL: Repository, https://github.com/htamber1/sqldoc
8
+ Keywords: sql-server,documentation,database,schema,er-diagram
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Environment :: Console
11
+ Classifier: Topic :: Database
12
+ Classifier: Topic :: Documentation
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: anthropic>=0.109
16
+ Requires-Dist: click>=8.1
17
+ Requires-Dist: Jinja2>=3.1
18
+ Requires-Dist: pyodbc>=5.0
19
+ Requires-Dist: python-dotenv>=1.0
20
+ Requires-Dist: PyYAML>=6.0
21
+ Requires-Dist: fpdf2>=2.8
22
+ Requires-Dist: requests>=2.31
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest>=8; extra == "test"
25
+ Requires-Dist: pypdf>=4; extra == "test"
26
+
27
+ # sqldoc
28
+
29
+ [![CI](https://github.com/htamber1/sqldoc/actions/workflows/ci.yml/badge.svg)](https://github.com/htamber1/sqldoc/actions/workflows/ci.yml)
30
+
31
+ Automated documentation generator for **SQL Server** databases.
32
+
33
+ `sqldoc` connects to a SQL Server database, extracts its schema, uses an LLM to
34
+ write plain-English descriptions of every table and column, and renders it all
35
+ into a single self-contained HTML file you can open in any browser or hand to a
36
+ colleague.
37
+
38
+ ## 🔒 Privacy guarantee
39
+
40
+ **sqldoc runs on-premise by default and never reads your data.**
41
+
42
+ - **Local by default.** In the default local mode, all AI processing runs against
43
+ a [Ollama](https://ollama.com) instance on your own machine. **No data of any
44
+ kind leaves your network** — not schema, not metadata, nothing.
45
+ - **Row data is never read.** sqldoc queries only SQL Server's `sys.*` catalog
46
+ views. It does not issue a single `SELECT` against your tables, so actual row
47
+ data is never read, stored, or transmitted — in *any* mode.
48
+ - **Cloud is opt-in and explicit.** Sending anything off-network requires
49
+ `--mode cloud`, which prints a warning and requires interactive confirmation
50
+ before making a network call. Even then, only *schema metadata* (table/column
51
+ names, data types, keys, and row counts) is sent to the Anthropic API.
52
+
53
+ This makes sqldoc safe to run against production and regulated databases: the
54
+ worst-case disclosure in cloud mode is a column *name* like `Employee.Salary` —
55
+ never a salary.
56
+
57
+ ## What it does
58
+
59
+ 1. **Extracts** schema metadata from the `sys.*` catalog views — tables, columns,
60
+ data types, primary/foreign keys, row counts, indexes, views (with their SQL
61
+ definitions), stored procedures (with parameters), and any existing
62
+ `MS_Description` extended properties.
63
+ 2. **Enriches** it with AI-generated descriptions: a short summary for each table,
64
+ view, and stored procedure, plus a one-line description for each column that
65
+ doesn't already have one. Enrichment runs concurrently (see `--concurrency`),
66
+ retries transient failures with exponential backoff, and caches descriptions
67
+ so re-running only regenerates objects whose structure changed.
68
+ 3. **Renders** a standalone HTML document — grouped by schema, with an ER diagram,
69
+ real-time search, and collapsible view/procedure definitions, styled inline,
70
+ no external assets or dependencies to serve.
71
+
72
+ ### HTML output — an IDE-like reading experience
73
+
74
+ The HTML report is a self-contained, dark-themed app (one file, no external
75
+ assets) built for navigating large schemas:
76
+
77
+ - **Sidebar navigation tree** — a collapsible left panel lists every schema and
78
+ its tables/views/procedures (type-tagged); click any item to smooth-scroll to
79
+ its card. The whole sidebar and each schema node collapse.
80
+ - **Interactive ER diagram** — schema-banded left-to-right layout showing only
81
+ FK-connected tables, with arrows colored by schema. Hover a table to spotlight
82
+ its relationships; click it to jump to its documentation card.
83
+ - **Real-time search + type filter** — filter to All / Tables / Views /
84
+ Procedures and search across names and columns at once.
85
+ - **Copy SQL** — one-click copy button on every view and stored-procedure
86
+ definition.
87
+ - **Color-coded row counts** — green pills for populated tables, gray for empty
88
+ ones, with thousands separators.
89
+
90
+ ## Requirements
91
+
92
+ - **Python 3.10+**
93
+ - **Microsoft ODBC Driver 18 for SQL Server** installed on the host
94
+ ([download](https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server)).
95
+ This is a system package, not a pip dependency.
96
+ - For **local mode**: a running [Ollama](https://ollama.com) with a model pulled
97
+ (default `llama3.1:8b` — `ollama pull llama3.1:8b`).
98
+ - For **cloud mode**: an Anthropic API key.
99
+
100
+ ## Installation
101
+
102
+ ```bash
103
+ python -m venv venv
104
+ venv/Scripts/activate # Windows; source venv/bin/activate on macOS/Linux
105
+ pip install . # installs sqldoc and the `sqldoc` command
106
+ ```
107
+
108
+ Use `pip install -e .` for an editable/development install. For cloud mode,
109
+ create a `.env` file in the working directory with your API key:
110
+
111
+ ```
112
+ ANTHROPIC_API_KEY=sk-ant-...
113
+ ```
114
+
115
+ ## Usage
116
+
117
+ sqldoc has two subcommands — **`sqldoc doc`** (generate documentation) and
118
+ **`sqldoc scan`** (scan for PII / compliance). For backward compatibility,
119
+ `sqldoc` with options but no subcommand runs `doc`:
120
+
121
+ ```bash
122
+ sqldoc doc --server <host> --database <db> --username <user> --password <pw> \
123
+ --output docs.html
124
+ # equivalently: sqldoc --server <host> ... --output docs.html
125
+ ```
126
+
127
+ You can also run it as a module without installing (`python -m sqldoc.cli ...`).
128
+
129
+ ```bash
130
+ python -m sqldoc.cli --server <host> --database <db> \
131
+ --username <user> --password <pw> --output docs.html
132
+ ```
133
+
134
+ ### Examples
135
+
136
+ Local mode (default — uses Ollama, nothing leaves your network):
137
+
138
+ ```bash
139
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
140
+ --username sa --password '***' --output docs.html
141
+ ```
142
+
143
+ Cloud mode (Anthropic — prompts for confirmation before sending metadata):
144
+
145
+ ```bash
146
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
147
+ --username sa --password '***' --mode cloud --output docs.html
148
+ ```
149
+
150
+ Schema-only, no AI (fastest; nothing leaves the machine):
151
+
152
+ ```bash
153
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
154
+ --username sa --password '***' --no-ai --output docs.html
155
+ ```
156
+
157
+ Markdown export for a GitHub wiki (format inferred from the `.md` extension):
158
+
159
+ ```bash
160
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
161
+ --username sa --password '***' --no-ai --output docs.md
162
+ ```
163
+
164
+ PDF export (self-contained, no system libraries — uses `fpdf2`):
165
+
166
+ ```bash
167
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
168
+ --username sa --password '***' --no-ai --output docs.pdf
169
+ ```
170
+
171
+ ### Options
172
+
173
+ | Option | Description |
174
+ | --- | --- |
175
+ | `--server` | SQL Server hostname or IP (**required**) |
176
+ | `--database` | Database name to document (**required**) |
177
+ | `--username` | SQL Server username (**required**) |
178
+ | `--password` | SQL Server password (**required**) |
179
+ | `--connection-string` | Full ODBC connection string — an alternative to the four flags above |
180
+ | `--output` | Output file path (default `documentation.html`) |
181
+ | `--format html\|markdown\|pdf` | Output format. Defaults to the `--output` extension (`.md`→markdown, `.pdf`→pdf), else HTML |
182
+ | `--mode local\|cloud` | AI backend: `local` (Ollama, default) or `cloud` (Anthropic) |
183
+ | `--model` | Model to use. Defaults per mode: `llama3.1:8b` (local), `claude-haiku-4-5` (cloud) |
184
+ | `--schemas` | Comma-separated list of schemas to include (default: all) |
185
+ | `--no-ai` | Skip AI descriptions, output schema only |
186
+ | `--concurrency` | Parallel AI calls during enrichment, 1-64 (default `8`) |
187
+ | `--snapshot` | JSON schema-snapshot path for change detection (default `.sqldoc-snapshots/<database>.json`) |
188
+ | `--no-snapshot` | Disable schema snapshot + change detection for this run |
189
+ | `--cache` | AI description cache path (default `.sqldoc-cache/<database>.json`) |
190
+ | `--no-cache` | Disable the AI description cache (always regenerate) |
191
+ | `--config` | Path to a config file (default `.sqldoc.yml` if present) |
192
+ | `--yes` / `-y` | Skip the cloud-mode confirmation prompt (for non-interactive/CI use) |
193
+
194
+ Instead of the four connection flags you can pass a single
195
+ `--connection-string` (handy for enterprise/Azure connection strings); the
196
+ database name is parsed from it for labeling. Any option (and the connection
197
+ flags) can also be supplied from a config file — see below.
198
+
199
+ ```bash
200
+ python -m sqldoc.cli --connection-string \
201
+ "DRIVER={ODBC Driver 18 for SQL Server};SERVER=host;DATABASE=Sales;UID=user;PWD=***;TrustServerCertificate=yes;" \
202
+ --output docs.html
203
+ ```
204
+
205
+ ## Config file
206
+
207
+ Rather than passing the same flags every run, drop a `.sqldoc.yml` in the working
208
+ directory. Every key maps to the CLI option of the same name; an explicitly
209
+ passed CLI flag always overrides the config, which in turn overrides the built-in
210
+ defaults. Copy [`.sqldoc.example.yml`](.sqldoc.example.yml) to get started:
211
+
212
+ ```yaml
213
+ server: localhost
214
+ database: AdventureWorks2022
215
+ username: sa
216
+ mode: local
217
+ concurrency: 8
218
+ # password: better supplied via --password than committed to disk
219
+ ```
220
+
221
+ Then simply:
222
+
223
+ ```bash
224
+ python -m sqldoc.cli --output docs.html # reads .sqldoc.yml
225
+ python -m sqldoc.cli --mode cloud --output docs.html # override just one setting
226
+ ```
227
+
228
+ > `.sqldoc.yml` is **gitignored** because it can contain a database password.
229
+ > Keep secrets out of it (use `--password` or `.env`) if you plan to share it.
230
+
231
+ ## Schema change detection
232
+
233
+ Every run writes a JSON snapshot of the schema's *structure* (object names,
234
+ column types, keys, indexes, parameters — never descriptions or row data) to
235
+ `.sqldoc-snapshots/<database>.json`. On the next run, sqldoc diffs the live
236
+ schema against that snapshot and prints what changed, like a git diff for your
237
+ database:
238
+
239
+ ```text
240
+ Schema changes since last run (.sqldoc-snapshots/AdventureWorks2022.json):
241
+ + table Sales.Promotion (6 columns)
242
+ - table dbo.LegacyAudit
243
+ ~ table HumanResources.Employee
244
+ + column PreferredName
245
+ - column MiddleName
246
+ ~ column MaritalStatus: type int -> nchar
247
+ + view Sales.vActiveCustomers
248
+ Schema changes: 1 table(s) added, 1 table(s) removed, 1 table(s) modified, 1 view/proc change(s)
249
+ ```
250
+
251
+ New/dropped tables, new/dropped columns, and type/nullability/key changes are
252
+ all reported. The first run just saves a baseline. Disable with `--no-snapshot`,
253
+ or point somewhere specific with `--snapshot path.json`. Snapshots are
254
+ gitignored by default; commit them intentionally if you want cross-commit or CI
255
+ change tracking.
256
+
257
+ ## PII / compliance scanning
258
+
259
+ `sqldoc scan` turns sqldoc into a compliance tool. It identifies columns that
260
+ likely hold personal or regulated data and writes a self-contained HTML
261
+ compliance report — a risk dashboard, per-column **HIGH / MEDIUM / LOW** ratings,
262
+ the regulation each finding maps to (**HIPAA / GDPR / PCI-DSS**), recommended
263
+ actions, and a CSV export.
264
+
265
+ ```bash
266
+ # Name + data-type analysis only — reads no row data:
267
+ sqldoc scan --server localhost --database AdventureWorks2022 \
268
+ --username sa --password '***' --output pii-report.html
269
+ ```
270
+
271
+ Detection matches column names (SSN, national ID, credit card, email, phone,
272
+ date of birth, passport, address, credentials, …) and confirms with the data
273
+ type. Add **`--sample`** to read up to 5 values per flagged column and have the
274
+ AI confirm whether they look like real PII:
275
+
276
+ ```bash
277
+ sqldoc scan --server localhost --database AdventureWorks2022 \
278
+ --username sa --password '***' --sample --mode local --output pii-report.html
279
+ ```
280
+
281
+ > `--sample` reads real values (which may be actual PII) purely to score
282
+ > confidence — **sampled values are never stored**, only the verdict. It is
283
+ > opt-in and prompts for confirmation; in cloud mode the samples are sent to the
284
+ > API, so prefer `--mode local` for sampling.
285
+
286
+ **PII drift** — each scan snapshots its findings; the next scan reports new,
287
+ resolved, and risk-changed findings (like schema change detection, for regulated
288
+ data). `--baseline PATH` / `--no-baseline`.
289
+
290
+ **CI gating** — `--fail-on high` exits non-zero if any HIGH finding exists;
291
+ `--fail-on new-high` fails only on a *new* HIGH finding vs the baseline. Combine
292
+ with `--sarif` to both gate the build and upload findings.
293
+
294
+ **SARIF export** — add `--sarif findings.sarif` to also emit SARIF 2.1.0 for
295
+ **GitHub Advanced Security** / **Azure DevOps**, so PII findings appear in the
296
+ security dashboard and can gate CI:
297
+
298
+ ```bash
299
+ sqldoc scan --server localhost --database AdventureWorks2022 \
300
+ --username sa --password '***' --sarif findings.sarif
301
+ ```
302
+
303
+ **Custom patterns** — define org-specific sensitive-column categories in
304
+ `.sqldoc.yml` under `pii_patterns:` (checked before the built-in catalog). See
305
+ [`.sqldoc.example.yml`](.sqldoc.example.yml):
306
+
307
+ ```yaml
308
+ pii_patterns:
309
+ - category: "Employee ID"
310
+ patterns: ['\bempid\b', 'employeenumber']
311
+ severity: MEDIUM # HIGH / MEDIUM / LOW
312
+ regulations: ["Internal Policy"]
313
+ action: "Restrict to HR systems."
314
+ types: [varchar, nvarchar] # optional; a matching type confirms
315
+ ```
316
+
317
+ ## How it works
318
+
319
+ `sqldoc` is a three-stage pipeline, one module per stage:
320
+
321
+ - `sqldoc/extractor.py` — queries the `sys.*` catalog views and builds `Table` /
322
+ `Column` / `Index` / `View` / `StoredProcedure` dataclasses.
323
+ - `sqldoc/ai.py` — fills in descriptions via Ollama (local) or the Anthropic SDK
324
+ (cloud), running the calls concurrently across a thread pool.
325
+ - `sqldoc/renderer.py` — renders the enriched data to a single HTML file.
sqldoc-1.3.0/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # sqldoc
2
+
3
+ [![CI](https://github.com/htamber1/sqldoc/actions/workflows/ci.yml/badge.svg)](https://github.com/htamber1/sqldoc/actions/workflows/ci.yml)
4
+
5
+ Automated documentation generator for **SQL Server** databases.
6
+
7
+ `sqldoc` connects to a SQL Server database, extracts its schema, uses an LLM to
8
+ write plain-English descriptions of every table and column, and renders it all
9
+ into a single self-contained HTML file you can open in any browser or hand to a
10
+ colleague.
11
+
12
+ ## 🔒 Privacy guarantee
13
+
14
+ **sqldoc runs on-premise by default and never reads your data.**
15
+
16
+ - **Local by default.** In the default local mode, all AI processing runs against
17
+ a [Ollama](https://ollama.com) instance on your own machine. **No data of any
18
+ kind leaves your network** — not schema, not metadata, nothing.
19
+ - **Row data is never read.** sqldoc queries only SQL Server's `sys.*` catalog
20
+ views. It does not issue a single `SELECT` against your tables, so actual row
21
+ data is never read, stored, or transmitted — in *any* mode.
22
+ - **Cloud is opt-in and explicit.** Sending anything off-network requires
23
+ `--mode cloud`, which prints a warning and requires interactive confirmation
24
+ before making a network call. Even then, only *schema metadata* (table/column
25
+ names, data types, keys, and row counts) is sent to the Anthropic API.
26
+
27
+ This makes sqldoc safe to run against production and regulated databases: the
28
+ worst-case disclosure in cloud mode is a column *name* like `Employee.Salary` —
29
+ never a salary.
30
+
31
+ ## What it does
32
+
33
+ 1. **Extracts** schema metadata from the `sys.*` catalog views — tables, columns,
34
+ data types, primary/foreign keys, row counts, indexes, views (with their SQL
35
+ definitions), stored procedures (with parameters), and any existing
36
+ `MS_Description` extended properties.
37
+ 2. **Enriches** it with AI-generated descriptions: a short summary for each table,
38
+ view, and stored procedure, plus a one-line description for each column that
39
+ doesn't already have one. Enrichment runs concurrently (see `--concurrency`),
40
+ retries transient failures with exponential backoff, and caches descriptions
41
+ so re-running only regenerates objects whose structure changed.
42
+ 3. **Renders** a standalone HTML document — grouped by schema, with an ER diagram,
43
+ real-time search, and collapsible view/procedure definitions, styled inline,
44
+ no external assets or dependencies to serve.
45
+
46
+ ### HTML output — an IDE-like reading experience
47
+
48
+ The HTML report is a self-contained, dark-themed app (one file, no external
49
+ assets) built for navigating large schemas:
50
+
51
+ - **Sidebar navigation tree** — a collapsible left panel lists every schema and
52
+ its tables/views/procedures (type-tagged); click any item to smooth-scroll to
53
+ its card. The whole sidebar and each schema node collapse.
54
+ - **Interactive ER diagram** — schema-banded left-to-right layout showing only
55
+ FK-connected tables, with arrows colored by schema. Hover a table to spotlight
56
+ its relationships; click it to jump to its documentation card.
57
+ - **Real-time search + type filter** — filter to All / Tables / Views /
58
+ Procedures and search across names and columns at once.
59
+ - **Copy SQL** — one-click copy button on every view and stored-procedure
60
+ definition.
61
+ - **Color-coded row counts** — green pills for populated tables, gray for empty
62
+ ones, with thousands separators.
63
+
64
+ ## Requirements
65
+
66
+ - **Python 3.10+**
67
+ - **Microsoft ODBC Driver 18 for SQL Server** installed on the host
68
+ ([download](https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server)).
69
+ This is a system package, not a pip dependency.
70
+ - For **local mode**: a running [Ollama](https://ollama.com) with a model pulled
71
+ (default `llama3.1:8b` — `ollama pull llama3.1:8b`).
72
+ - For **cloud mode**: an Anthropic API key.
73
+
74
+ ## Installation
75
+
76
+ ```bash
77
+ python -m venv venv
78
+ venv/Scripts/activate # Windows; source venv/bin/activate on macOS/Linux
79
+ pip install . # installs sqldoc and the `sqldoc` command
80
+ ```
81
+
82
+ Use `pip install -e .` for an editable/development install. For cloud mode,
83
+ create a `.env` file in the working directory with your API key:
84
+
85
+ ```
86
+ ANTHROPIC_API_KEY=sk-ant-...
87
+ ```
88
+
89
+ ## Usage
90
+
91
+ sqldoc has two subcommands — **`sqldoc doc`** (generate documentation) and
92
+ **`sqldoc scan`** (scan for PII / compliance). For backward compatibility,
93
+ `sqldoc` with options but no subcommand runs `doc`:
94
+
95
+ ```bash
96
+ sqldoc doc --server <host> --database <db> --username <user> --password <pw> \
97
+ --output docs.html
98
+ # equivalently: sqldoc --server <host> ... --output docs.html
99
+ ```
100
+
101
+ You can also run it as a module without installing (`python -m sqldoc.cli ...`).
102
+
103
+ ```bash
104
+ python -m sqldoc.cli --server <host> --database <db> \
105
+ --username <user> --password <pw> --output docs.html
106
+ ```
107
+
108
+ ### Examples
109
+
110
+ Local mode (default — uses Ollama, nothing leaves your network):
111
+
112
+ ```bash
113
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
114
+ --username sa --password '***' --output docs.html
115
+ ```
116
+
117
+ Cloud mode (Anthropic — prompts for confirmation before sending metadata):
118
+
119
+ ```bash
120
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
121
+ --username sa --password '***' --mode cloud --output docs.html
122
+ ```
123
+
124
+ Schema-only, no AI (fastest; nothing leaves the machine):
125
+
126
+ ```bash
127
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
128
+ --username sa --password '***' --no-ai --output docs.html
129
+ ```
130
+
131
+ Markdown export for a GitHub wiki (format inferred from the `.md` extension):
132
+
133
+ ```bash
134
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
135
+ --username sa --password '***' --no-ai --output docs.md
136
+ ```
137
+
138
+ PDF export (self-contained, no system libraries — uses `fpdf2`):
139
+
140
+ ```bash
141
+ python -m sqldoc.cli --server localhost --database AdventureWorks2022 \
142
+ --username sa --password '***' --no-ai --output docs.pdf
143
+ ```
144
+
145
+ ### Options
146
+
147
+ | Option | Description |
148
+ | --- | --- |
149
+ | `--server` | SQL Server hostname or IP (**required**) |
150
+ | `--database` | Database name to document (**required**) |
151
+ | `--username` | SQL Server username (**required**) |
152
+ | `--password` | SQL Server password (**required**) |
153
+ | `--connection-string` | Full ODBC connection string — an alternative to the four flags above |
154
+ | `--output` | Output file path (default `documentation.html`) |
155
+ | `--format html\|markdown\|pdf` | Output format. Defaults to the `--output` extension (`.md`→markdown, `.pdf`→pdf), else HTML |
156
+ | `--mode local\|cloud` | AI backend: `local` (Ollama, default) or `cloud` (Anthropic) |
157
+ | `--model` | Model to use. Defaults per mode: `llama3.1:8b` (local), `claude-haiku-4-5` (cloud) |
158
+ | `--schemas` | Comma-separated list of schemas to include (default: all) |
159
+ | `--no-ai` | Skip AI descriptions, output schema only |
160
+ | `--concurrency` | Parallel AI calls during enrichment, 1-64 (default `8`) |
161
+ | `--snapshot` | JSON schema-snapshot path for change detection (default `.sqldoc-snapshots/<database>.json`) |
162
+ | `--no-snapshot` | Disable schema snapshot + change detection for this run |
163
+ | `--cache` | AI description cache path (default `.sqldoc-cache/<database>.json`) |
164
+ | `--no-cache` | Disable the AI description cache (always regenerate) |
165
+ | `--config` | Path to a config file (default `.sqldoc.yml` if present) |
166
+ | `--yes` / `-y` | Skip the cloud-mode confirmation prompt (for non-interactive/CI use) |
167
+
168
+ Instead of the four connection flags you can pass a single
169
+ `--connection-string` (handy for enterprise/Azure connection strings); the
170
+ database name is parsed from it for labeling. Any option (and the connection
171
+ flags) can also be supplied from a config file — see below.
172
+
173
+ ```bash
174
+ python -m sqldoc.cli --connection-string \
175
+ "DRIVER={ODBC Driver 18 for SQL Server};SERVER=host;DATABASE=Sales;UID=user;PWD=***;TrustServerCertificate=yes;" \
176
+ --output docs.html
177
+ ```
178
+
179
+ ## Config file
180
+
181
+ Rather than passing the same flags every run, drop a `.sqldoc.yml` in the working
182
+ directory. Every key maps to the CLI option of the same name; an explicitly
183
+ passed CLI flag always overrides the config, which in turn overrides the built-in
184
+ defaults. Copy [`.sqldoc.example.yml`](.sqldoc.example.yml) to get started:
185
+
186
+ ```yaml
187
+ server: localhost
188
+ database: AdventureWorks2022
189
+ username: sa
190
+ mode: local
191
+ concurrency: 8
192
+ # password: better supplied via --password than committed to disk
193
+ ```
194
+
195
+ Then simply:
196
+
197
+ ```bash
198
+ python -m sqldoc.cli --output docs.html # reads .sqldoc.yml
199
+ python -m sqldoc.cli --mode cloud --output docs.html # override just one setting
200
+ ```
201
+
202
+ > `.sqldoc.yml` is **gitignored** because it can contain a database password.
203
+ > Keep secrets out of it (use `--password` or `.env`) if you plan to share it.
204
+
205
+ ## Schema change detection
206
+
207
+ Every run writes a JSON snapshot of the schema's *structure* (object names,
208
+ column types, keys, indexes, parameters — never descriptions or row data) to
209
+ `.sqldoc-snapshots/<database>.json`. On the next run, sqldoc diffs the live
210
+ schema against that snapshot and prints what changed, like a git diff for your
211
+ database:
212
+
213
+ ```text
214
+ Schema changes since last run (.sqldoc-snapshots/AdventureWorks2022.json):
215
+ + table Sales.Promotion (6 columns)
216
+ - table dbo.LegacyAudit
217
+ ~ table HumanResources.Employee
218
+ + column PreferredName
219
+ - column MiddleName
220
+ ~ column MaritalStatus: type int -> nchar
221
+ + view Sales.vActiveCustomers
222
+ Schema changes: 1 table(s) added, 1 table(s) removed, 1 table(s) modified, 1 view/proc change(s)
223
+ ```
224
+
225
+ New/dropped tables, new/dropped columns, and type/nullability/key changes are
226
+ all reported. The first run just saves a baseline. Disable with `--no-snapshot`,
227
+ or point somewhere specific with `--snapshot path.json`. Snapshots are
228
+ gitignored by default; commit them intentionally if you want cross-commit or CI
229
+ change tracking.
230
+
231
+ ## PII / compliance scanning
232
+
233
+ `sqldoc scan` turns sqldoc into a compliance tool. It identifies columns that
234
+ likely hold personal or regulated data and writes a self-contained HTML
235
+ compliance report — a risk dashboard, per-column **HIGH / MEDIUM / LOW** ratings,
236
+ the regulation each finding maps to (**HIPAA / GDPR / PCI-DSS**), recommended
237
+ actions, and a CSV export.
238
+
239
+ ```bash
240
+ # Name + data-type analysis only — reads no row data:
241
+ sqldoc scan --server localhost --database AdventureWorks2022 \
242
+ --username sa --password '***' --output pii-report.html
243
+ ```
244
+
245
+ Detection matches column names (SSN, national ID, credit card, email, phone,
246
+ date of birth, passport, address, credentials, …) and confirms with the data
247
+ type. Add **`--sample`** to read up to 5 values per flagged column and have the
248
+ AI confirm whether they look like real PII:
249
+
250
+ ```bash
251
+ sqldoc scan --server localhost --database AdventureWorks2022 \
252
+ --username sa --password '***' --sample --mode local --output pii-report.html
253
+ ```
254
+
255
+ > `--sample` reads real values (which may be actual PII) purely to score
256
+ > confidence — **sampled values are never stored**, only the verdict. It is
257
+ > opt-in and prompts for confirmation; in cloud mode the samples are sent to the
258
+ > API, so prefer `--mode local` for sampling.
259
+
260
+ **PII drift** — each scan snapshots its findings; the next scan reports new,
261
+ resolved, and risk-changed findings (like schema change detection, for regulated
262
+ data). `--baseline PATH` / `--no-baseline`.
263
+
264
+ **CI gating** — `--fail-on high` exits non-zero if any HIGH finding exists;
265
+ `--fail-on new-high` fails only on a *new* HIGH finding vs the baseline. Combine
266
+ with `--sarif` to both gate the build and upload findings.
267
+
268
+ **SARIF export** — add `--sarif findings.sarif` to also emit SARIF 2.1.0 for
269
+ **GitHub Advanced Security** / **Azure DevOps**, so PII findings appear in the
270
+ security dashboard and can gate CI:
271
+
272
+ ```bash
273
+ sqldoc scan --server localhost --database AdventureWorks2022 \
274
+ --username sa --password '***' --sarif findings.sarif
275
+ ```
276
+
277
+ **Custom patterns** — define org-specific sensitive-column categories in
278
+ `.sqldoc.yml` under `pii_patterns:` (checked before the built-in catalog). See
279
+ [`.sqldoc.example.yml`](.sqldoc.example.yml):
280
+
281
+ ```yaml
282
+ pii_patterns:
283
+ - category: "Employee ID"
284
+ patterns: ['\bempid\b', 'employeenumber']
285
+ severity: MEDIUM # HIGH / MEDIUM / LOW
286
+ regulations: ["Internal Policy"]
287
+ action: "Restrict to HR systems."
288
+ types: [varchar, nvarchar] # optional; a matching type confirms
289
+ ```
290
+
291
+ ## How it works
292
+
293
+ `sqldoc` is a three-stage pipeline, one module per stage:
294
+
295
+ - `sqldoc/extractor.py` — queries the `sys.*` catalog views and builds `Table` /
296
+ `Column` / `Index` / `View` / `StoredProcedure` dataclasses.
297
+ - `sqldoc/ai.py` — fills in descriptions via Ollama (local) or the Anthropic SDK
298
+ (cloud), running the calls concurrently across a thread pool.
299
+ - `sqldoc/renderer.py` — renders the enriched data to a single HTML file.
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sqldoc"
7
+ version = "1.3.0"
8
+ description = "SQL Server database documentation generator + PII/compliance scanner, with optional AI-written descriptions."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [{ name = "htamber" }]
12
+ keywords = ["sql-server", "documentation", "database", "schema", "er-diagram"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Environment :: Console",
16
+ "Topic :: Database",
17
+ "Topic :: Documentation",
18
+ ]
19
+ dependencies = [
20
+ "anthropic>=0.109",
21
+ "click>=8.1",
22
+ "Jinja2>=3.1",
23
+ "pyodbc>=5.0",
24
+ "python-dotenv>=1.0",
25
+ "PyYAML>=6.0",
26
+ "fpdf2>=2.8",
27
+ "requests>=2.31",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ test = ["pytest>=8", "pypdf>=4"]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/htamber1/sqldoc"
35
+ Repository = "https://github.com/htamber1/sqldoc"
36
+
37
+ [project.scripts]
38
+ sqldoc = "sqldoc.cli:cli"
39
+
40
+ [tool.setuptools]
41
+ packages = ["sqldoc"]
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
sqldoc-1.3.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ __version__ = "1.3.0"