mockit-sql-engine 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.
- mockit_sql_engine-0.1.0/PKG-INFO +38 -0
- mockit_sql_engine-0.1.0/README.md +27 -0
- mockit_sql_engine-0.1.0/pyproject.toml +19 -0
- mockit_sql_engine-0.1.0/setup.cfg +4 -0
- mockit_sql_engine-0.1.0/src/mockit/__init__.py +0 -0
- mockit_sql_engine-0.1.0/src/mockit/cli.py +46 -0
- mockit_sql_engine-0.1.0/src/mockit/engine.py +124 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/PKG-INFO +38 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/SOURCES.txt +11 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/dependency_links.txt +1 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/entry_points.txt +2 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/requires.txt +4 -0
- mockit_sql_engine-0.1.0/src/mockit_sql_engine.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mockit-sql-engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight CLI to mock DB schemas locally
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
8
|
+
Requires-Dist: faker>=19.0.0
|
|
9
|
+
Requires-Dist: click>=8.0.0
|
|
10
|
+
Requires-Dist: psycopg2-binary
|
|
11
|
+
|
|
12
|
+
# MockIt 🚀
|
|
13
|
+
|
|
14
|
+
[](https://pypi.org/project/mockit/)
|
|
15
|
+
[](https://opensource.org/licenses/MIT)
|
|
16
|
+
|
|
17
|
+
**Replicate cloud database schemas locally with high-fidelity synthetic data.**
|
|
18
|
+
|
|
19
|
+
MockIt is a CLI-first developer tool designed for Data Engineers who want to escape the high costs and latency of testing against production cloud warehouses like AWS Redshift or Snowflake.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🌟 Key Features
|
|
24
|
+
|
|
25
|
+
* **Schema Reflection**: Automatically inspects source tables and clones their structure (columns, types, nullability) to a local target.
|
|
26
|
+
* **Smart Type Mapping**: Intelligently maps SQL types to relevant `Faker` providers (e.g., `JSON` columns get JSON objects, `VARCHAR(email)` gets realistic email addresses).
|
|
27
|
+
* **Constraint Stripping**: Automatically removes Foreign Key constraints during local replication to allow for isolated table testing.
|
|
28
|
+
* **Identity Management**: Handles `SERIAL` and `IDENTITY` columns by skipping manual inserts, allowing the local database to manage primary keys.
|
|
29
|
+
* **Transaction Safety**: Built on SQLAlchemy 2.0 for robust, atomic data injections.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Installation
|
|
34
|
+
|
|
35
|
+
Install MockIt via pip:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install mockit
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# MockIt 🚀
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/mockit/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**Replicate cloud database schemas locally with high-fidelity synthetic data.**
|
|
7
|
+
|
|
8
|
+
MockIt is a CLI-first developer tool designed for Data Engineers who want to escape the high costs and latency of testing against production cloud warehouses like AWS Redshift or Snowflake.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🌟 Key Features
|
|
13
|
+
|
|
14
|
+
* **Schema Reflection**: Automatically inspects source tables and clones their structure (columns, types, nullability) to a local target.
|
|
15
|
+
* **Smart Type Mapping**: Intelligently maps SQL types to relevant `Faker` providers (e.g., `JSON` columns get JSON objects, `VARCHAR(email)` gets realistic email addresses).
|
|
16
|
+
* **Constraint Stripping**: Automatically removes Foreign Key constraints during local replication to allow for isolated table testing.
|
|
17
|
+
* **Identity Management**: Handles `SERIAL` and `IDENTITY` columns by skipping manual inserts, allowing the local database to manage primary keys.
|
|
18
|
+
* **Transaction Safety**: Built on SQLAlchemy 2.0 for robust, atomic data injections.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Installation
|
|
23
|
+
|
|
24
|
+
Install MockIt via pip:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install mockit
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mockit-sql-engine"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A lightweight CLI to mock DB schemas locally"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"sqlalchemy>=2.0.0",
|
|
13
|
+
"faker>=19.0.0",
|
|
14
|
+
"click>=8.0.0",
|
|
15
|
+
"psycopg2-binary"
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
mockit = "mockit.cli:main"
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import logging
|
|
3
|
+
from .engine import mock_table
|
|
4
|
+
|
|
5
|
+
# Disable extra SQLAlchemy logging unless the user wants --debug
|
|
6
|
+
logging.basicConfig(level=logging.WARNING)
|
|
7
|
+
|
|
8
|
+
@click.command()
|
|
9
|
+
@click.option('--source', required=True, help='Source DB URI (e.g. Redshift/Prod)')
|
|
10
|
+
@click.option('--target', required=True, help='Target DB URI (e.g. Local Postgres)')
|
|
11
|
+
@click.option('--table', required=True, help='Table name (can be schema.table)')
|
|
12
|
+
@click.option('--rows', default=10, type=int, help='Number of rows to generate')
|
|
13
|
+
@click.option('--reset', is_flag=True, default=True, help='Wipe target table before inserting (True by default)')
|
|
14
|
+
@click.option('--debug', is_flag=True, help='Show full stack trace on error')
|
|
15
|
+
def main(source, target, table, rows, reset, debug):
|
|
16
|
+
"""🚀 MockIt: Recreate prod schemas locally with fake data."""
|
|
17
|
+
|
|
18
|
+
if debug:
|
|
19
|
+
logging.getLogger("mockit").setLevel(logging.INFO)
|
|
20
|
+
|
|
21
|
+
click.secho(f"🔍 Analyzing schema for {table}...", fg='cyan')
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
# We pass the 'reset' flag to the 'truncate' parameter in engine.py
|
|
25
|
+
mock_table(
|
|
26
|
+
source_uri=source,
|
|
27
|
+
target_uri=target,
|
|
28
|
+
table_name=table,
|
|
29
|
+
row_count=rows,
|
|
30
|
+
truncate=reset
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
click.secho(f"✨ Success!", fg='green', bold=True)
|
|
34
|
+
click.echo(f" - Table: {table}")
|
|
35
|
+
click.echo(f" - Rows Created: {rows}")
|
|
36
|
+
click.echo(f" - Reset Performed: {reset}")
|
|
37
|
+
|
|
38
|
+
except Exception as e:
|
|
39
|
+
click.secho(f"❌ Error: {e}", fg='red', err=True)
|
|
40
|
+
if not debug:
|
|
41
|
+
click.echo("\n💡 Tip: Use --debug for a full stack trace or check your DB credentials.")
|
|
42
|
+
else:
|
|
43
|
+
raise e
|
|
44
|
+
|
|
45
|
+
if __name__ == '__main__':
|
|
46
|
+
main()
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import sqlalchemy as sa
|
|
2
|
+
from sqlalchemy import create_engine, MetaData, Table, insert, text
|
|
3
|
+
from sqlalchemy.engine import reflection
|
|
4
|
+
from faker import Faker
|
|
5
|
+
import random
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
# Setup professional logging
|
|
9
|
+
logging.basicConfig(level=logging.INFO)
|
|
10
|
+
logger = logging.getLogger("mockit")
|
|
11
|
+
|
|
12
|
+
fake = Faker()
|
|
13
|
+
|
|
14
|
+
def get_mock_value(column):
|
|
15
|
+
"""
|
|
16
|
+
Advanced mapping of SQL types and column names to Faker providers.
|
|
17
|
+
Handles standard types, strings with length limits, and common names.
|
|
18
|
+
"""
|
|
19
|
+
name = column.name.lower()
|
|
20
|
+
# Get the string representation of the type (e.g., 'INTEGER', 'VARCHAR(50)', 'JSONB')
|
|
21
|
+
ctype = str(column.type).upper()
|
|
22
|
+
|
|
23
|
+
# 1. Specialized Name-based Smarts (Highest Priority)
|
|
24
|
+
if "email" in name: return fake.email()
|
|
25
|
+
if "user" in name or "name" in name: return fake.name()
|
|
26
|
+
if "city" in name: return fake.city()
|
|
27
|
+
if "phone" in name: return fake.phone_number()
|
|
28
|
+
if "status" in name: return random.choice(['SUCCESS', 'FAILED', 'PENDING', 'ACTIVE'])
|
|
29
|
+
if "url" in name: return fake.url()
|
|
30
|
+
|
|
31
|
+
# 2. Complex Type Handling (JSON/UUID)
|
|
32
|
+
if "JSON" in ctype:
|
|
33
|
+
return {"id": random.randint(1, 100), "mocked": True, "data": fake.word()}
|
|
34
|
+
if "UUID" in ctype:
|
|
35
|
+
return fake.uuid4()
|
|
36
|
+
|
|
37
|
+
# 3. Numeric Types
|
|
38
|
+
if "INT" in ctype:
|
|
39
|
+
return random.randint(1, 1000)
|
|
40
|
+
if any(x in ctype for x in ["NUMERIC", "DECIMAL", "FLOAT", "DOUBLE"]):
|
|
41
|
+
return round(random.uniform(10.0, 500.0), 2)
|
|
42
|
+
|
|
43
|
+
# 4. Boolean
|
|
44
|
+
if "BOOL" in ctype:
|
|
45
|
+
return random.choice([True, False])
|
|
46
|
+
|
|
47
|
+
# 5. Dates & Timestamps
|
|
48
|
+
if "DATE" in ctype or "TIME" in ctype:
|
|
49
|
+
return fake.date_time_this_year()
|
|
50
|
+
|
|
51
|
+
# 6. String/Varchar with Length Protection
|
|
52
|
+
if "CHAR" in ctype or "TEXT" in ctype:
|
|
53
|
+
# Respect VARCHAR(N) limits if they exist to prevent 'value too long' errors
|
|
54
|
+
limit = getattr(column.type, 'length', None)
|
|
55
|
+
val = fake.word() if not limit or limit > 10 else fake.lexify("????")
|
|
56
|
+
return val[:limit] if limit else val
|
|
57
|
+
|
|
58
|
+
# Final Fallback
|
|
59
|
+
return fake.word()
|
|
60
|
+
|
|
61
|
+
def mock_table(source_uri, target_uri, table_name, row_count, truncate=True):
|
|
62
|
+
"""
|
|
63
|
+
Enterprise-grade table mocking:
|
|
64
|
+
- Reflects source schema (Redshift/Postgres/etc)
|
|
65
|
+
- Replicates structure to local Target
|
|
66
|
+
- Strips constraints that cause local failures (FKs)
|
|
67
|
+
- Generates type-safe fake data
|
|
68
|
+
"""
|
|
69
|
+
src_engine = create_engine(source_uri)
|
|
70
|
+
tgt_engine = create_engine(target_uri)
|
|
71
|
+
|
|
72
|
+
schema = None
|
|
73
|
+
actual_table_name = table_name
|
|
74
|
+
if "." in table_name:
|
|
75
|
+
schema, actual_table_name = table_name.split(".")
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
# 1. Reflect Source Blueprint
|
|
79
|
+
metadata_src = MetaData()
|
|
80
|
+
source_table = Table(actual_table_name, metadata_src, autoload_with=src_engine, schema=schema)
|
|
81
|
+
logger.info(f"Reflected source schema for {table_name}")
|
|
82
|
+
|
|
83
|
+
# 2. Build Local Target Blueprint
|
|
84
|
+
metadata_tgt = MetaData()
|
|
85
|
+
target_table = Table(actual_table_name, metadata_tgt, schema=schema)
|
|
86
|
+
|
|
87
|
+
for col in source_table.columns:
|
|
88
|
+
new_col = col.copy()
|
|
89
|
+
# Disable unique constraints and clear Foreign Keys to allow isolated testing
|
|
90
|
+
new_col.unique = False
|
|
91
|
+
new_col.foreign_keys.clear()
|
|
92
|
+
target_table.append_column(new_col)
|
|
93
|
+
|
|
94
|
+
# 3. Create Table on Local Target if missing
|
|
95
|
+
metadata_tgt.create_all(tgt_engine)
|
|
96
|
+
|
|
97
|
+
# 4. Clean Slate (Truncate)
|
|
98
|
+
if truncate:
|
|
99
|
+
with tgt_engine.begin() as conn:
|
|
100
|
+
# Use RESTART IDENTITY to reset SERIAL counters to 1
|
|
101
|
+
full_name = f"{schema}.{actual_table_name}" if schema else actual_table_name
|
|
102
|
+
conn.execute(text(f"TRUNCATE TABLE {full_name} RESTART IDENTITY CASCADE;"))
|
|
103
|
+
logger.info(f"Table {full_name} truncated and identities reset.")
|
|
104
|
+
|
|
105
|
+
# 5. Generate Smart Mock Data
|
|
106
|
+
mock_rows = []
|
|
107
|
+
for _ in range(row_count):
|
|
108
|
+
row_data = {}
|
|
109
|
+
for col in target_table.columns:
|
|
110
|
+
# Skip Auto-increment columns; let Local Postgres generate IDs
|
|
111
|
+
if col.primary_key and col.autoincrement:
|
|
112
|
+
continue
|
|
113
|
+
row_data[col.name] = get_mock_value(col)
|
|
114
|
+
mock_rows.append(row_data)
|
|
115
|
+
|
|
116
|
+
# 6. Bulk Insert into Local
|
|
117
|
+
with tgt_engine.begin() as conn:
|
|
118
|
+
conn.execute(insert(target_table), mock_rows)
|
|
119
|
+
|
|
120
|
+
logger.info(f"✅ Successfully injected {row_count} mock rows into {table_name}")
|
|
121
|
+
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logger.error(f"❌ Robust Mocking Failed: {str(e)}")
|
|
124
|
+
raise e
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mockit-sql-engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight CLI to mock DB schemas locally
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
8
|
+
Requires-Dist: faker>=19.0.0
|
|
9
|
+
Requires-Dist: click>=8.0.0
|
|
10
|
+
Requires-Dist: psycopg2-binary
|
|
11
|
+
|
|
12
|
+
# MockIt 🚀
|
|
13
|
+
|
|
14
|
+
[](https://pypi.org/project/mockit/)
|
|
15
|
+
[](https://opensource.org/licenses/MIT)
|
|
16
|
+
|
|
17
|
+
**Replicate cloud database schemas locally with high-fidelity synthetic data.**
|
|
18
|
+
|
|
19
|
+
MockIt is a CLI-first developer tool designed for Data Engineers who want to escape the high costs and latency of testing against production cloud warehouses like AWS Redshift or Snowflake.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🌟 Key Features
|
|
24
|
+
|
|
25
|
+
* **Schema Reflection**: Automatically inspects source tables and clones their structure (columns, types, nullability) to a local target.
|
|
26
|
+
* **Smart Type Mapping**: Intelligently maps SQL types to relevant `Faker` providers (e.g., `JSON` columns get JSON objects, `VARCHAR(email)` gets realistic email addresses).
|
|
27
|
+
* **Constraint Stripping**: Automatically removes Foreign Key constraints during local replication to allow for isolated table testing.
|
|
28
|
+
* **Identity Management**: Handles `SERIAL` and `IDENTITY` columns by skipping manual inserts, allowing the local database to manage primary keys.
|
|
29
|
+
* **Transaction Safety**: Built on SQLAlchemy 2.0 for robust, atomic data injections.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Installation
|
|
34
|
+
|
|
35
|
+
Install MockIt via pip:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install mockit
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/mockit/__init__.py
|
|
4
|
+
src/mockit/cli.py
|
|
5
|
+
src/mockit/engine.py
|
|
6
|
+
src/mockit_sql_engine.egg-info/PKG-INFO
|
|
7
|
+
src/mockit_sql_engine.egg-info/SOURCES.txt
|
|
8
|
+
src/mockit_sql_engine.egg-info/dependency_links.txt
|
|
9
|
+
src/mockit_sql_engine.egg-info/entry_points.txt
|
|
10
|
+
src/mockit_sql_engine.egg-info/requires.txt
|
|
11
|
+
src/mockit_sql_engine.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mockit
|