
# Misata
**经证实可靠的合成数据 —— 通过一句话、YAML 或您自己的数据库,生成逼真的多表数据集及验证报告。**
[](https://pypi.org/project/misata/)
[](https://pypi.org/project/misata/)
[](https://github.com/rasinmuhammed/misata/actions)
[](LICENSE)
[](https://colab.research.google.com/github/rasinmuhammed/misata/blob/main/notebooks/quickstart.ipynb)
Misata 可以从纯英文描述、YAML schema 文件或现有的数据库 schema 中生成一致且引用完整的多表数据集。每次常规的生成运行还可以写入一份 **Oracle 报告**:这是一份可共享的证明包,包含了行数、引用完整性、约束、时间一致性、区域/领域契合度、隐私说明、保真度评分和可复现性元数据。
无需机器学习模型。不需要真实数据。
专为以下场景构建:
- **数据库填充** — 用类似生产环境的数据填充开发和预发环境
- **集成测试** — 拥有跨表外键 (FK) 完整性的关联夹具
- **演示和原型设计** — 逼真的数字、名称和分布,不包含个人身份信息 (PII)
- **BI 和仪表板开发** — 在正式上线前拥有与真实领域形态相似的数据
## 安装说明
```
pip install misata
```
可选的附加功能:
```
pip install "misata[llm]" # multi-provider LLM schema generation
pip install "misata[documents]" # PDF output via weasyprint
pip install "misata[advanced]" # SDV/CTGAN statistical synthesis
pip install "misata[mcp]" # MCP server — expose Misata to Claude, Cursor, and other AI agents
```
## 从 Claude / Cursor / Windsurf (MCP) 使用 Misata
Misata 内置了 [Model Context Protocol](https://modelcontextprotocol.io) 服务器。配置完成后,任何兼容 MCP 的 AI 助手都可以通过自然语言为您生成逼真的合成数据 —— 您的终端无需安装 Python。
**1. 安装:**
```
pip install "misata[mcp]"
```
**2. 添加到 Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```
{
"mcpServers": {
"misata": {
"command": "misata-mcp"
}
}
}
```
重启 Claude Desktop。然后只需问:
Claude 会调用 Misata,将 CSV 文件写入磁盘,并返回文件路径及每个表的预览。有关 Cursor/Windsurf/Zed 的设置及全部五个可用工具,请参见 [MCP 指南](docs/guides/mcp.md)。
## 快速开始
```
misata generate \
--story "Brazilian fintech with R$ payments, CPF verification, and 3% fraud" \
--rows 1000 \
--output-dir ./demo_data
# 写入 CSV 以及:
# ./demo_data/oracle_report.json
```
```
import misata
# 单句 → 多表 DataFrame 字典
tables = misata.generate("A SaaS company with 5k users, monthly subscriptions, and 20% churn")
print(tables["users"].head())
print(tables["subscriptions"].head())
```
```
# 或者通过 CLI
misata generate --story "A SaaS company with 5k users and 20% churn" --rows 5000
```
## Misata Oracle
Oracle 报告是 Misata 的验证层。它将硬性保证与建议性的真实性检查区分开来,以便生成的数据可以在 CI、演示、Notebook 和研究对比中获得信任。
硬性检查:
- 跨配置关系的引用完整性
- 满足请求的行数
- schema 验证和配置的约束
- 设定种子时的确定性可复现性
建议性检查:
- 质量评分和合理性警告
- 隐私启发式评估
- schema 与输出的保真度评分
- 针对国家、城市、电话区号和国民身份证的区域/领域契合度
- 数据卡元数据
```
import misata
schema = misata.parse("Brazilian fintech with CPF verification", rows=1000)
tables = misata.generate_from_schema(schema)
oracle = misata.build_oracle_report(tables, schema, seed=schema.seed)
print(oracle["passed"])
print(oracle["advisory"]["locale_domain_fit"]["locale"])
```
## 生成数据的六种方式
### 1. 纯英文描述 — 无需配置
```
tables = misata.generate("A fintech startup with 10k customers, fraud rate 3%, and IBAN accounts")
```
Misata 会阅读描述文本,推断领域(金融科技)、规模(10,000 行)和列语义(欺诈标志、IBAN 格式) —— 无需手动编写 schema。
### 2. YAML schema 即代码 — 将其提交到 git
```
misata init # scaffolds misata.yaml in the current directory
misata generate # reads misata.yaml automatically
```
```
# misata.yaml
name: my-app
seed: 42
tables:
users:
rows: 1000
columns:
user_id: { type: int, unique: true }
email: { type: text, text_type: email }
plan: { type: categorical, choices: [free, pro, enterprise] }
orders:
rows: 5000
columns:
order_id: { type: int, unique: true }
user_id: { type: foreign_key }
amount: { type: float, min: 5.0, max: 500.0 }
relationships:
- "users.user_id → orders.user_id"
constraints:
- name: amount_above_cost
table: orders
type: inequality
column_a: amount
operator: ">"
column_b: cost
```
```
schema = misata.load_yaml_schema("misata.yaml")
tables = misata.generate_from_schema(schema)
```
### 3. 直接填充现有数据库
```
from misata import schema_from_db, generate_from_schema, seed_database
# 自省实时 schema —— 无需手动定义列
schema = schema_from_db("postgresql://user:pass@localhost/myapp")
tables = generate_from_schema(schema)
# 将其回种 —— 插入顺序自动遵循 FK 依赖
report = seed_database(tables, "postgresql://user:pass@localhost/myapp_dev")
# SeedReport: 已回种 6 张表, 47,300 行, 耗时 1.2s
```
```
# 单命令工作流
misata init --db postgresql://user:pass@localhost/myapp # writes misata.yaml
misata generate --db-url postgresql://user:pass@localhost/myapp_dev --db-create
```
也支持 SQLAlchemy 模型:
```
from misata import seed_from_sqlalchemy_models
from myapp.models import Base
report = seed_from_sqlalchemy_models(Base, db_url="sqlite:///test.db", row_count=500, create_tables=True)
```
### 4. Python 字典 schema
```
schema = misata.from_dict_schema({
"customers": {
"id": {"type": "integer", "primary_key": True},
"email": {"type": "email"},
"plan": {"type": "string", "enum": ["free", "pro", "enterprise"]},
},
"orders": {
"id": {"type": "integer", "primary_key": True},
"customer_id": {"type": "integer", "foreign_key": {"table": "customers", "column": "id"}},
"amount": {"type": "float", "min": 1.0, "max": 999.0},
},
}, row_count=5_000)
tables = misata.generate_from_schema(schema)
```
### 5. LLM 辅助生成 — 更丰富的语义,可选
```
from misata import LLMSchemaGenerator
gen = LLMSchemaGenerator(provider="groq") # free tier, fast
# gen = LLMSchemaGenerator(provider="anthropic") # Claude
# gen = LLMSchemaGenerator(provider="ollama", model="llama3") # 完全本地, 无需 API key
schema = gen.generate_from_story(
"A fraud detection dataset — 2% positive rate, FICO scores, transaction velocity features"
)
tables = misata.generate_from_schema(schema)
```
需要安装 `pip install "misata[llm]"`,并设置 `GROQ_API_KEY`、`OPENAI_API_KEY`、`ANTHROPIC_API_KEY` 或 `GOOGLE_API_KEY` 之一。
### 6. 增量生成 — 无需重新填充即可扩展数据集
```
tables = misata.generate("A fintech company with 1000 customers", seed=1)
# 再新增 1 000 行 —— ID 自动偏移, 两批次间保持 FK 完整性
tables = misata.generate_more(tables, schema, n=1000, seed=2)
print(len(tables["customers"])) # 2000
```
## 本地化
Misata 会自动从您的描述文本中检测国家背景,并为该区域生成统计上准确的数据 —— 包括正确的姓名、薪资分布、国民身份证格式、货币、邮政编码和公司命名惯例。
```
# 自动检测 Locale —— 无需额外标志
tables = misata.generate("German SaaS company in Berlin with 2k enterprise customers")
# → 姓名来自 de_DE Faker 池, salary ~ lognormal(μ=10.71, σ=0.5) ≈ €45k median,
# 邮编为 5 位, 公司名以 GmbH/AG/UG 结尾
tables = misata.generate("Brazilian fintech with R$ payments and CPF verification, 50k users")
# → pt_BR 姓名, salary 中位数 ~BRL 33.6k, national ID 符合 CPF 格式 ###.###.###-##
tables = misata.generate("Indian startup in Bangalore with ₹ salary bands and Aadhaar KYC")
# → hi_IN 姓名, salary 中位数 ~₹350k/yr, national ID 符合 Aadhaar 12位格式
```
显式强制或覆盖区域设置:
```
schema = misata.parse("An ecommerce store with 10k orders")
tables = misata.generate_from_schema(schema) # defaults to en_US
# CLI
misata generate --story "Ecommerce store" --locale ja_JP
```
### 15 个内置区域
| 区域 | 国家 | 货币 | 薪资中位数 | 国民身份证 |
|:--|:--|:--|--:|:--|
| `en_US` | United States | USD / $ | $62 000 | SSN `###-##-####` |
| `en_GB` | United Kingdom | GBP / £ | £34 000 | NIN `AA######A` |
| `de_DE` | Germany | EUR / € | €45 000 | Steuer-IdNr |
| `fr_FR` | France | EUR / € | €38 000 | NIR |
| `pt_BR` | Brazil | BRL / R$ | R$33 600 | CPF `###.###.###-##` |
| `es_ES` | Spain | EUR / € | €27 000 | NIE |
| `hi_IN` | India | INR / ₹ | ₹350 000 | Aadhaar `####-####-####` |
| `ja_JP` | Japan | JPY / ¥ | ¥4 400 000 | My Number |
| `zh_CN` | China | CNY / ¥ | ¥90 000 | Resident ID |
| `ar_SA` | Saudi Arabia | SAR | SAR 96 000 | National ID |
| `ko_KR` | South Korea | KRW / ₩ | ₩42 000 000 | RRN |
| `nl_NL` | Netherlands | EUR / € | €42 000 | BSN |
| `it_IT` | Italy | EUR / € | €29 000 | Codice Fiscale |
| `pl_PL` | Poland | PLN | PLN 72 000 | PESEL |
| `tr_TR` | Turkey | TRY | TRY 720 000 | TC Kimlik |
每个数据包都包含真实的薪资分布(中位数和对数正态先验)、年龄分布、排名前列的城市、电话号码前缀、邮政编码模式、公司名称后缀和增值税税率 —— 数据来源于经合组织 (OECD)、世界银行、国际劳工组织和国家统计局(2023-24 年数据)。
```
# 直接检查 locale 包
pack = misata.get_locale_pack("de_DE")
print(pack.salary_median) # 45000
print(pack.currency_symbol) # €
print(pack.top_cities[:3]) # ['Berlin', 'Hamburg', 'Munich']
print(pack.company_suffixes) # ['GmbH', 'AG', 'UG', 'KG', 'e.K.']
# 从 story 自动检测
locale = misata.detect_locale("South Korean company in Seoul with KRW salaries")
# → "ko_KR"
```
## 约束
强制执行贯穿每一行生成的业务规则:
```
from misata.constraints import (
InequalityConstraint, # price > cost on every row
ColumnRangeConstraint, # min_price <= price <= max_price
RatioConstraint, # 70% free / 30% pro
UniqueConstraint, # no duplicate (user_id, date) pairs
SumConstraint, # total_hours per employee per day <= 8
NotNullConstraint, # no nulls in required columns
)
c = InequalityConstraint("price", ">", "cost")
df = c.apply(df)
```
约束也可以在 `misata.yaml` 中声明 —— 它们在生成时运行,而不是作为后处理步骤。
## 导出
```
misata.to_parquet(tables, "data/")
misata.to_duckdb(tables, "data/dataset.duckdb")
misata.to_jsonl(tables, "data/")
```
## 文档生成
从任何表格中为每一行渲染一个文档 —— 适用于需要端到端看起来都很逼真的演示数据集:
```
# 内置模板: invoice, patient_report, transaction_receipt, user_profile
paths = misata.generate_documents(
tables, "invoice", table="orders", output_dir="/tmp/invoices", format="html"
)
# format="pdf" 需: pip install "misata[documents]"
# 自定义 Jinja2 模板
tmpl = "
Order #{{ order_id }}
Amount: ${{ amount }}
"
paths = misata.generate_documents(tables, tmpl, table="orders", output_dir="/tmp/custom")
```
## 质量与隐私分析
```
bundle = misata.analyze_generation(tables, schema)
print(bundle.data_card.summary()) # row counts, null rates, type distribution
print(bundle.fidelity_report.score) # 0–1 statistical fidelity score vs. schema intent
print(bundle.privacy_report.pii_risk) # column-level PII exposure analysis
```
## 支持的领域
18 个内置领域 schema —— 每个都能生成一个完全关联的多表数据集,具有逼真的分布、外键 (FK) 完整性和领域相关的列语义。
| 领域 | 触发关键词 | 生成的表 |
|:--|:--|:--|
| SaaS | saas, subscription, mrr, churn | users, subscriptions, invoices |
| 电子商务 | ecommerce, orders, store, retail | customers, products, orders, order_items |
| 金融科技 | fintech, payments, banking, fraud | customers, accounts, transactions |
| 医疗保健 | healthcare, patients, doctors, clinic | doctors, patients, appointments |
| 交易平台 | marketplace, sellers, buyers, listings | sellers, buyers, listings, orders |
| 物流 | logistics, shipping, drivers, routes | drivers, vehicles, routes, shipments |
| HR | hr, employees, payroll, workforce | departments, employees, payroll |
| 社交 | social media, instagram, feed, followers | users, posts, follows, reactions |
| 房地产 | real estate, housing, mortgage | agents, properties, transactions |
| 制药 | pharma, clinical, trials | researchers, projects, trials, timesheets |
| 外卖配送 | food delivery, restaurant, takeout | restaurants, customers, couriers, orders, order_items |
| EdTech | edtech, courses, students, enrollments | instructors, courses, students, enrollments, quiz_attempts |
| 游戏 | gaming, players, leaderboard, esports | players, matches, sessions, achievements |
| CRM | crm, salesforce, deals, pipeline | companies, contacts, deals, activities |
| Crypto / Web3 | crypto, blockchain, ethereum, defi | wallets, tokens, transactions, token_prices |
| 保险 | insurance, policy, claims, premium | customers, policies, claims, payments |
| 旅游 | travel, hotel, flights, bookings | users, hotels, flights, bookings, reviews |
| 流媒体 | streaming, netflix, subscribers, watch history | subscribers, content, watch_history, ratings |
未匹配到关键词 → 具有智能列推断的通用单表 schema。
## 工作原理
```
story / YAML / dict / DB introspection / MCP tool call
↓
StoryParser · locale detection · load_yaml_schema · schema_from_db
↓
DetectionReport (domain, confidence, near_misses, table_preview, warnings)
↓
SchemaConfig ← validate_schema() catches issues before any rows are generated
↓
DataSimulator
├─ topological sort (FK dependency order)
├─ domain priors → locale priors (salary, age, monetary)
├─ constraint engine (inequality, range, ratio, sum, unique)
├─ outcome curves (monthly targets from narrative control points)
├─ Iman-Conover correlation engine (Cholesky, preserves marginals)
└─ RealisticTextGenerator (Faker locale + Kaggle vocabulary assets)
↓
{table_name: DataFrame}
↓
seed_database · to_parquet · to_duckdb · generate_documents · MCP CSV output
```
**领域先验** — 货币列使用对数正态分布。分类数据使用 Zipf 采样。血型、国家分布和薪资区间反映了现实世界的统计数据。
**区域先验** — 薪资和年龄分布会被源自国家统计局的特定国家/地区的对数正态/正态参数覆盖。在您的描述中的 `"Brazilian fintech"` 意味着薪资将从 BRL 分布中采样,而不是 USD。
**结果曲线** — 自然语言描述会被解析为精确的月度控制点。命名事件、季度和乘数都支持:
```
# 所有这些都会生成精确且成型的结果曲线:
misata.generate("SaaS mrr from $50k in Jan to $200k in Dec, with a Q3 slump")
misata.generate("Ecommerce orders, Black Friday spike, Christmas peak")
misata.generate("SaaS startup — MRR 10x growth over the year")
misata.generate("Fintech payments — strong Q4, dip in Q1")
```
**真实性规则** — `cost` 总是小于 `price`。`delivered_at` 总是在 `shipped_at` 之后。`hire_date` 在 `date_of_birth` + 18 年之后且永远不会是未来的时间。`tenure_years` 是在同一行中从 `hire_date` 派生出来的。电子邮件地址是从名字和姓氏列派生出来的。
## Misata 的独特之处
| | Faker | Synth | syda | SDV | **Misata** |
|:--|:--:|:--:|:--:|:--:|:--:|
| 无需配置,一行代码生成多表数据 | — | — | — | — | **Yes** |
| 描述自动检测区域 + 国家统计数据 | — | — | — | — | **Yes** |
| 18 个内置领域 schema (SaaS → 流媒体) | — | — | — | — | **Yes** |
| 叙事曲线 (Q4 促销、黑色星期五、10×) | — | — | — | — | **Yes** |
| 模仿模式 — 从 CSV 克隆分布 | — | — | — | **Yes** | **Yes** |
| 成对相关性强制执行 (Iman-Conover) | — | — | — | **Yes** | **Yes** |
| 地理空间列 (lat, lng, postal_code) | — | — | — | — | **Yes** |
| 异常注入 (每列异常率) | — | — | — | — | **Yes** |
| MCP 服务器 — 可从 Claude / Cursor 使用 | — | — | — | — | **Yes** |
| 提交到 git 的 YAML schema | — | **Yes** | **Yes** | — | **Yes** |
| JSON Schema 验证 + 编辑器自动补全 | — | — | — | — | **Yes** |
| 数据库内省 → 生成 → 重新填充 | — | **Yes** | — | Limited | **Yes** |
| 直接数据库填充 (Postgres / MySQL / SQLite) | — | — | — | — | **Yes** |
| SQLAlchemy 模型填充 | — | — | — | — | **Yes** |
| 跨所有 FK 表的引用完整性 | — | **Yes** | **Yes** | **Yes** | **Yes** |
| 不等式/范围约束 (`price > cost`) | — | Limited | — | **Yes** | **Yes** |
| 聚合目标曲线 (月度 MRR 形状) | — | — | — | — | **Yes** |
| 领域真实的分布 | — | — | — | Limited | **Yes** |
| 多提供商 LLM (Groq / OpenAI / Claude / Gemini / Ollama) | — | — | **Yes** | — | **Yes** |
| 完全离线,无需 LLM | **Yes** | **Yes** | — | **Yes** | **Yes** |
| 文档生成 (每行生成 HTML / PDF) | — | — | — | — | **Yes** |
| 质量 + 隐私 | — | — | — | Limited | **Yes** |
| 纯 Python,无需外部服务 | **Yes** | — | — | **Yes** | **Yes** |
**Faker** 生成单独的假数据 —— 不具备关联性,没有 schema,也没有统计准确性。
**Synth** 擅长 schema 即代码的 git 工作流;但分布控制有限。
**syda** 对每一行使用 LLM —— 语义丰富但昂贵、缓慢,并且需要 API 密钥。
**SDV** 从真实数据中学习 —— 这是一个不同的问题(您首先需要真实数据)。
**Misata** 基于意图生成数据,默认离线运行,直接填充数据库,并且现在能自动为每一列提供统计上准确的国家数据。
## 性能
在 Apple M 系列(单核,无 GPU)上测量:
| 工作负载 | 行数 | 时间 | 吞吐量 |
|:--|--:|--:|--:|
| 单表,对数正态分布 | 1 000 000 | 0.06 s | ~16M 行/秒 |
| 星型 schema (5 个表,4 个 FK) | 1 055 030 | 1.54 s | ~687k 行/秒 |
## 贡献指南
```
git clone https://github.com/rasinmuhammed/misata
cd misata
pip install -e ".[dev]"
pytest tests/
```
欢迎提交 Issue 和 PR — [github.com/rasinmuhammed/misata/issues](https://github.com/rasinmuhammed/misata/issues)