Files
docs/final-docs/03-DATA-MIGRATION.md
T
masoodafar-web 5965b98728 update
2026-01-03 18:27:49 +03:30

261 lines
7.0 KiB
Markdown

# 🔄 Data Migration Guide
> **آخرین بروزرسانی**: January 3, 2026
> **ابزار**: FourSat.DataMigration
> **تعداد جداول**: 33
> **وضعیت**: ✅ آماده برای Production
---
## 📋 نگاه اجمالی
این ابزار یک **ابزار یکبار مصرف** برای مهاجرت داده‌های دیتابیس از ساختار قدیمی (Production) به ساختار جدید (Stage) است.
**زمان تخمینی اجرا**: 5-10 دقیقه
**تکنولوژی**: .NET 9.0 + Dapper + PostgreSQL
---
## 📁 ساختار پروژه
```
DataMigration/
├── FourSat.DataMigration/
│ ├── Program.cs # Entry point
│ ├── appsettings.json # 33 table mappings
│ ├── Models/
│ │ └── MigrationModels.cs # Settings, Mapping, QueueItem
│ ├── Services/
│ │ └── MigrationService.cs # Migration + Post-Migration logic
│ └── Scripts/
│ └── PostMigration_DataTransformation.sql
└── FourSat.GeographySeeder/ # ابزار جداگانه برای Geography data
```
---
## 🚀 راهنمای سریع (3 قدم)
### قدم 1: ویرایش تنظیمات
```bash
cd DataMigration/FourSat.DataMigration
# ویرایش appsettings.json
```
```json
{
"SourceConnectionString": "Host=OLD_SERVER;Database=OLD_DB;Username=xxx;Password=xxx",
"DestinationConnectionString": "Host=NEW_SERVER;Database=NEW_DB;Username=xxx;Password=xxx"
}
```
### قدم 2: اجرای Migration
```bash
dotnet run
```
### قدم 3: بررسی Logs
```bash
# خروجی:
[Users] Migrated 50000 rows in 12.5s
[Products] Migrated 8500 rows in 3.2s
...
✅ Migration completed! Total: 33 tables, Time: 4m 32s
```
---
## 📋 لیست جداول (33 جدول)
### جداول با تغییر نام (10 جدول)
| نام قدیمی (Source) | نام جدید (Target) | دلیل تغییر |
|-------------------|-------------------|-----------|
| `Categorys` | `Categories` | جمع صحیح Category |
| `FactorDetailss` | `FactorDetails` | s اضافی |
| `ProductGalleryss` | `ProductGalleries` | Gallery → Galleries |
| `ProductImagess` | `ProductImages` | s اضافی |
| `Productss` | `Products` | s اضافی |
| `PruductCategorys` | `ProductCategories` | Pruduct → Product |
| `PruductTags` | `ProductTags` | Pruduct → Product |
| `Transactionss` | `Transactions` | s اضافی |
| `UserAddresss` | `UserAddresses` | s اضافی |
| `UserCartss` | `UserCarts` | s اضافی |
### جداول بدون تغییر نام (23 جدول)
| گروه | جداول |
|------|--------|
| Core | `Roles`, `Tags`, `SystemConfigurations`, `ClubFeatures`, `Packages` |
| Users | `Users`, `OtpTokens`, `UserRoles`, `UserWallets`, `UserAddresses`, `UserCarts` |
| Products | `Categories`, `Products`, `ProductImages`, `ProductGalleries`, `ProductCategories`, `ProductTags` |
| Club | `ClubMemberships`, `ClubMembershipHistories`, `UserClubFeatures` |
| Network | `NetworkWeeklyBalances`, `NetworkMembershipHistories` |
| Commission | `CommissionPayoutHistories`, `UserCommissionPayouts`, `WeeklyCommissionPools` |
| Orders | `UserOrders`, `Transactions`, `Contracts`, `UserContracts` |
---
## 🔄 Post-Migration Transformation
### Binary Tree User Conversion
پس از migrate کردن جدول `Users`، باید تبدیل داده‌های شبکه انجام شود:
**مشکل**: در دیتابیس قدیمی، ستون‌های `Left` و `Right` شامل username است. در جدید باید UserId باشد.
**Script**: `PostMigration_DataTransformation.sql`
```sql
-- Convert username to user_id for binary tree
UPDATE "Users" u
SET
"LeftId" = (SELECT "Id" FROM "Users" WHERE "Username" = u."LeftUsername"),
"RightId" = (SELECT "Id" FROM "Users" WHERE "Username" = u."RightUsername")
WHERE "LeftUsername" IS NOT NULL OR "RightUsername" IS NOT NULL;
```
---
## ⚙️ تنظیمات پیشرفته
### appsettings.json
```json
{
"SourceConnectionString": "Host=...;Database=...;Username=...;Password=...",
"DestinationConnectionString": "Host=...;Database=...;Username=...;Password=...",
"BatchSize": 5000,
"MaxRetries": 3,
"RetryDelaySeconds": 5,
"TableMappings": [
{
"SourceTable": "Categorys",
"DestinationTable": "Categories",
"Priority": 1,
"ColumnMappings": {
"Id": "Id",
"Name": "Name",
"ParentId": "ParentId"
}
}
// ... 32 more tables
]
}
```
### تنظیمات کلیدی:
| تنظیم | پیش‌فرض | توضیحات |
|-------|---------|---------|
| `BatchSize` | 5000 | تعداد rows در هر batch |
| `MaxRetries` | 3 | تلاش مجدد در صورت خطا |
| `RetryDelaySeconds` | 5 | تأخیر بین retries |
| `Priority` | 1-5 | ترتیب migration (1=اول) |
---
## 🔧 ترتیب Migration
### مرحله 1: جداول پایه (بدون FK)
```
Roles → Tags → SystemConfigurations → ClubFeatures → Packages
```
### مرحله 2: جداول کاربری
```
Users → OtpTokens → UserRoles → UserWallets → UserAddresses → UserCarts
```
### مرحله 3: جداول محصولات
```
Categories → Products → ProductImages → ProductGalleries → ProductCategories → ProductTags
```
### مرحله 4: جداول عضویت
```
ClubMemberships → ClubMembershipHistories → NetworkWeeklyBalances
```
### مرحله 5: جداول تراکنش
```
UserOrders → Transactions → Contracts
```
---
## 🛠️ عیب‌یابی
### مشکل: FK Constraint Violation
**علامت**:
```
ERROR: insert or update on table "UserRoles" violates foreign key constraint
```
**راه‌حل**: بررسی Priority در appsettings.json - جدول parent باید Priority کمتر داشته باشد
---
### مشکل: Duplicate Key
**علامت**:
```
ERROR: duplicate key value violates unique constraint
```
**راه‌حل**:
```sql
-- پاک کردن destination قبل از migration
TRUNCATE TABLE "TargetTable" CASCADE;
```
---
### مشکل: Connection Timeout
**علامت**:
```
Npgsql.NpgsqlException: Timeout during reading attempt
```
**راه‌حل**: کاهش `BatchSize` به 1000
---
## ✅ چک‌لیست قبل از اجرا
- [ ] دسترسی به هر دو دیتابیس تست شده
- [ ] Backup از destination database گرفته شده
- [ ] Connection strings صحیح است
- [ ] BatchSize مناسب تنظیم شده
- [ ] Priority ها بررسی شده
- [ ] Post-Migration script آماده است
---
## 📊 آمار نهایی
| معیار | مقدار |
|-------|-------|
| تعداد جداول | 33 |
| جداول با تغییر نام | 10 |
| زمان تخمینی | 5-10 دقیقه |
| BatchSize پیش‌فرض | 5000 |
| MaxRetries | 3 |
---
## 📚 فایل‌های مرتبط
| فایل | توضیحات |
|------|---------|
| `appsettings.json` | تنظیمات و mapping ها |
| `MigrationService.cs` | لاجیک اصلی migration |
| `PostMigration_DataTransformation.sql` | Binary tree conversion |