UPDATE
This commit is contained in:
@@ -2,9 +2,10 @@ from django.db import migrations
|
||||
|
||||
|
||||
FARM_TYPES = {
|
||||
"زراعی": ["گندم", "ذرت"],
|
||||
"درختی": ["سیب", "پسته"],
|
||||
"زراعی": ["گندم", "ذرت", "جو", "کلزا", "پنبه"],
|
||||
"درختی": ["سیب", "پسته", "انگور", "انار"],
|
||||
"غرقابی": ["برنج"],
|
||||
"گلخانه ای": ["گوجه فرنگی", "خیار", "فلفل دلمه ای"],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.2.12 on 2026-03-20 00:30
|
||||
|
||||
import uuid
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("sensor_catalog", "0002_sensorcatalog_supported_power_sources"),
|
||||
("farm_hub", "0002_seed_default_catalog"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="farmsensor",
|
||||
name="physical_device_uuid",
|
||||
field=models.UUIDField(db_index=True, default=uuid.uuid4, unique=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="farmsensor",
|
||||
name="sensor_catalog",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
related_name="farm_sensors",
|
||||
to="sensor_catalog.sensorcatalog",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.2.12 on 2026-03-20 01:30
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("crop_zoning", "0004_croparea_farm"),
|
||||
("farm_hub", "0003_farmsensor_catalog_and_physical_device"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="farmhub",
|
||||
name="customization",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="farmsensor",
|
||||
name="customization",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="farmhub",
|
||||
name="current_crop_area",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="current_for_farms",
|
||||
to="crop_zoning.croparea",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,163 @@
|
||||
import json
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
DEFAULT_FARM_TYPE_NAME = "زراعی"
|
||||
|
||||
|
||||
def _table_exists(schema_editor, table_name):
|
||||
with schema_editor.connection.cursor() as cursor:
|
||||
existing_tables = set(schema_editor.connection.introspection.table_names(cursor))
|
||||
return table_name in existing_tables
|
||||
|
||||
|
||||
def _deserialize_json(value):
|
||||
if value in (None, "", b""):
|
||||
return {}
|
||||
if isinstance(value, (dict, list)):
|
||||
return value
|
||||
if isinstance(value, bytes):
|
||||
value = value.decode("utf-8")
|
||||
try:
|
||||
return json.loads(value)
|
||||
except (TypeError, ValueError):
|
||||
return {}
|
||||
|
||||
|
||||
def migrate_plant_rows_to_products(apps, schema_editor):
|
||||
if not _table_exists(schema_editor, "plant_plant"):
|
||||
return
|
||||
|
||||
FarmType = apps.get_model("farm_hub", "FarmType")
|
||||
Product = apps.get_model("farm_hub", "Product")
|
||||
|
||||
farm_type, _ = FarmType.objects.get_or_create(name=DEFAULT_FARM_TYPE_NAME)
|
||||
|
||||
with schema_editor.connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT
|
||||
name,
|
||||
light,
|
||||
watering,
|
||||
soil,
|
||||
temperature,
|
||||
planting_season,
|
||||
harvest_time,
|
||||
spacing,
|
||||
fertilizer,
|
||||
health_profile,
|
||||
irrigation_profile,
|
||||
growth_profile,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM plant_plant
|
||||
"""
|
||||
)
|
||||
columns = [column[0] for column in cursor.description]
|
||||
rows = [dict(zip(columns, row)) for row in cursor.fetchall()]
|
||||
|
||||
for row in rows:
|
||||
Product.objects.update_or_create(
|
||||
farm_type=farm_type,
|
||||
name=row["name"],
|
||||
defaults={
|
||||
"light": row["light"] or "",
|
||||
"watering": row["watering"] or "",
|
||||
"soil": row["soil"] or "",
|
||||
"temperature": row["temperature"] or "",
|
||||
"planting_season": row["planting_season"] or "",
|
||||
"harvest_time": row["harvest_time"] or "",
|
||||
"spacing": row["spacing"] or "",
|
||||
"fertilizer": row["fertilizer"] or "",
|
||||
"health_profile": _deserialize_json(row["health_profile"]),
|
||||
"irrigation_profile": _deserialize_json(row["irrigation_profile"]),
|
||||
"growth_profile": _deserialize_json(row["growth_profile"]),
|
||||
"created_at": row["created_at"],
|
||||
"updated_at": row["updated_at"],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def drop_legacy_plant_table(apps, schema_editor):
|
||||
if _table_exists(schema_editor, "plant_plant"):
|
||||
schema_editor.execute("DROP TABLE plant_plant")
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("farm_hub", "0004_remove_customization_add_current_crop_area"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="fertilizer",
|
||||
field=models.CharField(blank=True, default="", help_text="کود مناسب", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="growth_profile",
|
||||
field=models.JSONField(
|
||||
blank=True,
|
||||
default=dict,
|
||||
help_text='پروفایل رشد محصول برای مدل GDD. {"base_temperature": 10, "required_gdd_for_maturity": 1200, "stage_thresholds": {"flowering": 500, "fruiting": 850}, "current_cumulative_gdd": 320}',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="harvest_time",
|
||||
field=models.CharField(blank=True, default="", help_text="زمان برداشت", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="health_profile",
|
||||
field=models.JSONField(
|
||||
blank=True,
|
||||
default=dict,
|
||||
help_text='پروفایل سلامت محصول برای KPIها. ساختار نمونه: {"moisture": {"ideal_value": 65, "min_range": 45, "max_range": 75, "weight": 0.4}}',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="irrigation_profile",
|
||||
field=models.JSONField(
|
||||
blank=True,
|
||||
default=dict,
|
||||
help_text='پروفایل آبیاری محصول برای محاسبات ETc. {"kc_initial": 0.6, "kc_mid": 1.15, "kc_end": 0.8, "growth_stage_duration": {"initial": 20, "mid": 30, "late": 25}}',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="light",
|
||||
field=models.CharField(blank=True, default="", help_text="نور مورد نیاز", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="planting_season",
|
||||
field=models.CharField(blank=True, default="", help_text="فصل کاشت", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="soil",
|
||||
field=models.CharField(blank=True, default="", help_text="خاک مناسب", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="spacing",
|
||||
field=models.CharField(blank=True, default="", help_text="فاصله کاشت", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="temperature",
|
||||
field=models.CharField(blank=True, default="", help_text="دمای مناسب", max_length=255),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="watering",
|
||||
field=models.CharField(blank=True, default="", help_text="آبیاری", max_length=255),
|
||||
),
|
||||
migrations.RunPython(migrate_plant_rows_to_products, migrations.RunPython.noop),
|
||||
migrations.RunPython(drop_legacy_plant_table, migrations.RunPython.noop),
|
||||
]
|
||||
@@ -0,0 +1,55 @@
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
CATALOG_SEED_DATA = {
|
||||
"زراعی": [
|
||||
{"name": "گندم", "planting_season": "پاییز", "harvest_time": "اواخر بهار", "soil": "لومی"},
|
||||
{"name": "ذرت", "planting_season": "بهار", "harvest_time": "تابستان", "soil": "لومی شنی"},
|
||||
{"name": "جو", "planting_season": "پاییز", "harvest_time": "اواخر بهار", "soil": "لومی"},
|
||||
{"name": "کلزا", "planting_season": "پاییز", "harvest_time": "بهار", "soil": "لومی رسی"},
|
||||
{"name": "پنبه", "planting_season": "بهار", "harvest_time": "پاییز", "soil": "لومی"},
|
||||
],
|
||||
"درختی": [
|
||||
{"name": "سیب", "planting_season": "زمستان", "harvest_time": "پاییز", "soil": "لومی"},
|
||||
{"name": "پسته", "planting_season": "زمستان", "harvest_time": "اواخر تابستان", "soil": "شنی لومی"},
|
||||
{"name": "انگور", "planting_season": "اواخر زمستان", "harvest_time": "تابستان", "soil": "لومی"},
|
||||
{"name": "انار", "planting_season": "اواخر زمستان", "harvest_time": "پاییز", "soil": "لومی شنی"},
|
||||
],
|
||||
"غرقابی": [
|
||||
{"name": "برنج", "planting_season": "بهار", "harvest_time": "اواخر تابستان", "soil": "رسی"},
|
||||
],
|
||||
"گلخانه ای": [
|
||||
{"name": "گوجه فرنگی", "planting_season": "چهار فصل", "harvest_time": "چند مرحله ای", "soil": "کوکوپیت"},
|
||||
{"name": "خیار", "planting_season": "چهار فصل", "harvest_time": "چند مرحله ای", "soil": "پرلیت"},
|
||||
{"name": "فلفل دلمه ای", "planting_season": "چهار فصل", "harvest_time": "چند مرحله ای", "soil": "بستر هیدروپونیک"},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def seed_expanded_catalog(apps, schema_editor):
|
||||
FarmType = apps.get_model("farm_hub", "FarmType")
|
||||
Product = apps.get_model("farm_hub", "Product")
|
||||
|
||||
for farm_type_name, products in CATALOG_SEED_DATA.items():
|
||||
farm_type, _ = FarmType.objects.get_or_create(name=farm_type_name)
|
||||
for product_data in products:
|
||||
Product.objects.update_or_create(
|
||||
farm_type=farm_type,
|
||||
name=product_data["name"],
|
||||
defaults={key: value for key, value in product_data.items() if key != "name"},
|
||||
)
|
||||
|
||||
|
||||
def unseed_expanded_catalog(apps, schema_editor):
|
||||
FarmType = apps.get_model("farm_hub", "FarmType")
|
||||
FarmType.objects.filter(name__in=CATALOG_SEED_DATA.keys()).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("farm_hub", "0005_product_profiles_and_plant_migration"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_expanded_catalog, unseed_expanded_catalog),
|
||||
]
|
||||
Reference in New Issue
Block a user