sqlcarbon 0.1.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python:*)"
5
+ ]
6
+ }
7
+ }
@@ -0,0 +1,395 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqlcarbon
3
+ Version: 0.1.0
4
+ Summary: Reliable, deterministic SQL Server table-to-table copy tool
5
+ Project-URL: Homepage, https://github.com/yourusername/sqlcarbon
6
+ Project-URL: Issues, https://github.com/yourusername/sqlcarbon/issues
7
+ License: MIT
8
+ Keywords: data-migration,database,etl,sql,sqlserver
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: System Administrators
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Database
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: click>=8.0
20
+ Requires-Dist: pydantic>=2.0
21
+ Requires-Dist: pyodbc>=4.0
22
+ Requires-Dist: pyyaml>=6.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # SQLcarbon
26
+
27
+ **Reliable, deterministic SQL Server table-to-table copy tool.**
28
+
29
+ Copy tables between SQL Server instances with a single command or a few lines of Python — no SSIS, no BCP scripts, no fuss.
30
+
31
+ > Created by **TroBeeOne LLC**
32
+
33
+ ---
34
+
35
+ ## Features
36
+
37
+ - Copy tables across different SQL Server instances (same or different versions)
38
+ - Supports trusted (Windows) and SQL authentication
39
+ - Recreates schema: columns, identity columns (with correct seed/increment), computed columns
40
+ - Optionally copies indexes, check/default constraints, and extended properties
41
+ - Three copy modes: **full**, **schema_only**, **data_only**
42
+ - Chunked streaming reads with `fast_executemany` inserts — handles tables of any size
43
+ - Continues to the next job when one fails (configurable `stop_on_failure`)
44
+ - Clear, structured log files written to your working directory
45
+ - Version compatibility warnings (e.g., using `datetime2` against a SQL Server 2005 target)
46
+ - Use as a **CLI tool** or a **Python library**
47
+
48
+ ---
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install sqlcarbon
54
+ ```
55
+
56
+ Requires **Python 3.10+** and the [Microsoft ODBC Driver for SQL Server](https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server).
57
+
58
+ ---
59
+
60
+ ## Quick Start — CLI
61
+
62
+ ### 1. Generate a sample config
63
+
64
+ ```bash
65
+ sqlcarbon init > plan.yaml
66
+ ```
67
+
68
+ ### 2. Edit `plan.yaml`
69
+
70
+ ```yaml
71
+ connections:
72
+ my_source:
73
+ server: "sql01.example.com"
74
+ database: "Sales"
75
+ auth:
76
+ mode: "trusted"
77
+
78
+ my_dest:
79
+ server: "sql02.example.com"
80
+ database: "Archive"
81
+ auth:
82
+ mode: "sql"
83
+ username: "sa"
84
+ password: "yourpassword"
85
+
86
+ defaults:
87
+ batch_size: 100000
88
+ stop_on_failure: false
89
+ create_indexes: false
90
+ create_constraints: false
91
+ include_extended_properties: false
92
+ copy_mode: "full"
93
+ nolock: true
94
+
95
+ jobs:
96
+ - name: CopyCustomers
97
+ source_connection: my_source
98
+ destination_connection: my_dest
99
+ source_table: dbo.Customers
100
+ destination_table: dbo.Customers_Archive
101
+ ```
102
+
103
+ ### 3. Validate your config (no database changes)
104
+
105
+ ```bash
106
+ sqlcarbon validate plan.yaml
107
+ ```
108
+
109
+ ```
110
+ OK: Config is valid — 2 connection(s), 1 job(s).
111
+ ```
112
+
113
+ ### 4. Run it
114
+
115
+ ```bash
116
+ sqlcarbon run plan.yaml
117
+ ```
118
+
119
+ ```
120
+ 2026-03-08 10:00:01 INFO ============================================================
121
+ 2026-03-08 10:00:01 INFO Starting Job: [CopyCustomers]
122
+ 2026-03-08 10:00:01 INFO ============================================================
123
+ 2026-03-08 10:00:01 INFO [CopyCustomers] Source: sql01.example.com / Sales
124
+ 2026-03-08 10:00:01 INFO [CopyCustomers] Destination: sql02.example.com / Archive
125
+ 2026-03-08 10:00:01 INFO [CopyCustomers] Copy mode: full
126
+ 2026-03-08 10:00:02 INFO [CopyCustomers] Source: SQL Server 2019 | Destination: SQL Server 2019
127
+ 2026-03-08 10:00:02 INFO [CopyCustomers] Creating table [dbo].[Customers_Archive]...
128
+ 2026-03-08 10:00:02 INFO [CopyCustomers] Table created.
129
+ 2026-03-08 10:00:02 INFO [CopyCustomers] Starting data copy (batch_size=100,000, nolock=True)...
130
+ 2026-03-08 10:00:04 INFO [CopyCustomers] ... 100,000 rows inserted.
131
+ 2026-03-08 10:00:05 INFO [CopyCustomers] ... 185,432 rows inserted.
132
+ 2026-03-08 10:00:05 INFO [CopyCustomers] SUCCESS | rows=185,432 | duration=3.84s
133
+ ```
134
+
135
+ A log file is also written to your current directory: `sqlcarbon_20260308_100001.log`
136
+
137
+ ---
138
+
139
+ ## Quick Start — Python Library
140
+
141
+ ```python
142
+ from sqlcarbon import MigrationPlan, run_plan
143
+
144
+ plan = MigrationPlan.from_yaml("plan.yaml")
145
+ summary = run_plan(plan)
146
+
147
+ print(f"Succeeded: {summary.succeeded} / {summary.total_jobs}")
148
+ for result in summary.results:
149
+ print(f" {result.job_name}: {result.rows_copied:,} rows in {result.duration_seconds:.2f}s")
150
+ ```
151
+
152
+ ### Load from a Python dict
153
+
154
+ ```python
155
+ from sqlcarbon import MigrationPlan, run_plan
156
+
157
+ plan = MigrationPlan.from_dict({
158
+ "connections": {
159
+ "src": {
160
+ "server": "sql01.example.com",
161
+ "database": "Sales",
162
+ "auth": {"mode": "trusted"},
163
+ },
164
+ "dst": {
165
+ "server": "sql02.example.com",
166
+ "database": "Archive",
167
+ "auth": {"mode": "sql", "username": "sa", "password": "yourpassword"},
168
+ },
169
+ },
170
+ "jobs": [
171
+ {
172
+ "name": "CopyCustomers",
173
+ "source_connection": "src",
174
+ "destination_connection": "dst",
175
+ "source_table": "dbo.Customers",
176
+ "destination_table": "dbo.Customers_Archive",
177
+ }
178
+ ],
179
+ })
180
+
181
+ summary = run_plan(plan)
182
+ ```
183
+
184
+ ### Load from a YAML string
185
+
186
+ ```python
187
+ from sqlcarbon import MigrationPlan, run_plan
188
+
189
+ yaml_text = """
190
+ connections:
191
+ src:
192
+ server: "sql01.example.com"
193
+ database: "Sales"
194
+ auth:
195
+ mode: "trusted"
196
+ dst:
197
+ server: "sql02.example.com"
198
+ database: "Archive"
199
+ auth:
200
+ mode: "trusted"
201
+ jobs:
202
+ - name: CopyOrders
203
+ source_connection: src
204
+ destination_connection: dst
205
+ source_table: dbo.Orders
206
+ destination_table: dbo.Orders_Archive
207
+ """
208
+
209
+ plan = MigrationPlan.from_yaml_string(yaml_text)
210
+ summary = run_plan(plan)
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Configuration Reference
216
+
217
+ ### `connections`
218
+
219
+ Each named connection supports:
220
+
221
+ | Field | Required | Default | Description |
222
+ |-------|----------|---------|-------------|
223
+ | `server` | Yes | — | Server name, IP, or `server,port` / `server:port` |
224
+ | `database` | Yes | — | Target database name |
225
+ | `auth.mode` | No | `trusted` | `trusted` (Windows auth) or `sql` (SQL auth) |
226
+ | `auth.username` | If `sql` | — | SQL login username |
227
+ | `auth.password` | If `sql` | — | SQL login password |
228
+ | `driver` | No | `ODBC Driver 17 for SQL Server` | ODBC driver name |
229
+ | `trust_server_certificate` | No | `false` | Set `true` to bypass SSL certificate validation (equivalent to SSMS "Trust server certificate") |
230
+
231
+ **Custom port example:**
232
+ ```yaml
233
+ connections:
234
+ my_conn:
235
+ server: "sql01.example.com,1445"
236
+ database: "MyDB"
237
+ auth:
238
+ mode: "trusted"
239
+ ```
240
+
241
+ **ODBC Driver 18 example** (needed for newer SQL Server / Azure SQL):
242
+ ```yaml
243
+ connections:
244
+ my_conn:
245
+ server: "sql01.example.com"
246
+ database: "MyDB"
247
+ auth:
248
+ mode: "trusted"
249
+ driver: "ODBC Driver 18 for SQL Server"
250
+ trust_server_certificate: true # bypass cert validation (like SSMS checkbox)
251
+ ```
252
+
253
+ ---
254
+
255
+ ### `defaults`
256
+
257
+ Global defaults applied to all jobs unless overridden at the job level.
258
+
259
+ | Field | Default | Description |
260
+ |-------|---------|-------------|
261
+ | `batch_size` | `100000` | Rows per read/insert chunk |
262
+ | `stop_on_failure` | `false` | Stop all remaining jobs if one fails |
263
+ | `create_indexes` | `false` | Recreate indexes on destination |
264
+ | `create_constraints` | `false` | Recreate check and default constraints |
265
+ | `include_extended_properties` | `false` | Copy extended properties |
266
+ | `copy_mode` | `full` | `full`, `schema_only`, or `data_only` |
267
+ | `nolock` | `true` | Use `WITH (NOLOCK)` on source reads |
268
+
269
+ ---
270
+
271
+ ### `jobs`
272
+
273
+ Each job represents one table copy operation.
274
+
275
+ | Field | Required | Description |
276
+ |-------|----------|-------------|
277
+ | `name` | Yes | Friendly name shown in logs |
278
+ | `source_connection` | Yes | Name of a connection defined under `connections` |
279
+ | `destination_connection` | Yes | Name of a connection defined under `connections` |
280
+ | `source_table` | Yes | Source table, e.g. `dbo.Customers` |
281
+ | `destination_table` | Yes | Destination table, e.g. `dbo.Customers_Archive` |
282
+ | `options` | No | Per-job overrides (see below) |
283
+
284
+ **Per-job `options`** (all optional — fall back to `defaults` if omitted):
285
+
286
+ ```yaml
287
+ options:
288
+ batch_size: 50000
289
+ create_indexes: true
290
+ create_constraints: true
291
+ include_extended_properties: false
292
+ stop_on_failure: true
293
+ copy_mode: "schema_only"
294
+ ```
295
+
296
+ ---
297
+
298
+ ## Copy Modes
299
+
300
+ | Mode | Creates Table | Copies Data | Use When |
301
+ |------|:---:|:---:|----------|
302
+ | `full` (default) | Yes | Yes | Normal table archiving / migration |
303
+ | `schema_only` | Yes | No | Pre-create table structure before a data load |
304
+ | `data_only` | No | Yes | Destination table already exists; just load rows |
305
+
306
+ > **Safety:** SQLcarbon will **never** drop or truncate an existing table. If a destination table already exists when running `full` or `schema_only`, the job hard-fails with a clear error message and no data is touched.
307
+ >
308
+ > For `data_only`, if the destination table does **not** exist, the job hard-fails with a clear error message.
309
+
310
+ ---
311
+
312
+ ## Multiple Jobs Example
313
+
314
+ ```yaml
315
+ connections:
316
+ prod:
317
+ server: "sql-prod.example.com"
318
+ database: "Operations"
319
+ auth:
320
+ mode: "trusted"
321
+
322
+ archive:
323
+ server: "sql-archive.example.com"
324
+ database: "Archive2026"
325
+ auth:
326
+ mode: "trusted"
327
+
328
+ defaults:
329
+ batch_size: 100000
330
+ stop_on_failure: false
331
+ create_indexes: true
332
+ copy_mode: "full"
333
+ nolock: true
334
+
335
+ jobs:
336
+ - name: CopyCustomers
337
+ source_connection: prod
338
+ destination_connection: archive
339
+ source_table: dbo.Customers
340
+ destination_table: dbo.Customers
341
+
342
+ - name: CopyOrders
343
+ source_connection: prod
344
+ destination_connection: archive
345
+ source_table: dbo.Orders
346
+ destination_table: dbo.Orders
347
+ options:
348
+ stop_on_failure: true # stop everything if Orders fails
349
+
350
+ - name: CopyOrderLines
351
+ source_connection: prod
352
+ destination_connection: archive
353
+ source_table: dbo.OrderLines
354
+ destination_table: dbo.OrderLines
355
+
356
+ - name: SchemaOnlyProducts
357
+ source_connection: prod
358
+ destination_connection: archive
359
+ source_table: dbo.Products
360
+ destination_table: dbo.Products
361
+ options:
362
+ copy_mode: "schema_only"
363
+ create_indexes: true
364
+ create_constraints: true
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Behavior Notes
370
+
371
+ - **Identity columns** — SQLcarbon reads the exact seed and increment from the source and recreates them on the destination. `SET IDENTITY_INSERT ON/OFF` is handled automatically.
372
+ - **Computed columns** — Detected and recreated as computed columns on the destination. They are excluded from the data `INSERT` (SQL Server recalculates them automatically).
373
+ - **Partial failures** — If a batch insert fails mid-copy, SQLcarbon logs a clear `PARTIAL FAILURE` warning with the number of rows already committed. The partial data is left in place for inspection; SQLcarbon does not attempt cleanup.
374
+ - **Version compatibility** — If the source uses a data type not available on the destination (e.g., `datetime2` targeting SQL Server 2005), a warning is logged before the job runs. SQLcarbon does not attempt type transformations.
375
+
376
+ ---
377
+
378
+ ## CLI Reference
379
+
380
+ ```
381
+ sqlcarbon --help
382
+ sqlcarbon run <config.yaml> Run all jobs in the plan
383
+ sqlcarbon validate <config.yaml> Validate config without touching any database
384
+ sqlcarbon init Print a sample plan.yaml to stdout
385
+ ```
386
+
387
+ ---
388
+
389
+ ## License
390
+
391
+ MIT License — see `LICENSE` for details.
392
+
393
+ ---
394
+
395
+ *SQLcarbon is an open-source project initially created by **TroBeeOne LLC**.*