# Relaciones entre Modelos A76 ## Resumen de Relaciones Establecidas ### GPart (Tabla: gparts) El modelo `GPart` representa las partes/componentes en los sistemas SCAII, SCAF y WINSAAI. #### Relaciones: 1. **Con Country (public.countries)** - Campo: `country_of_origin` → `countries.m3_key` - Relación: Many-to-One - Propósito: País de origen de la parte 2. **Con CurrencyType (public.currency_types)** - Campo: `currency_key` → `currency_types.code` - Relación: Many-to-One - Propósito: Tipo de moneda para el costo unitario 3. **Con GClass (gclasses)** - Campos: `(client_key, part_class)` → `(client_key, class_code)` - Relación: Many-to-One (usando primaryjoin complejo) - Propósito: Clasificación de la parte - Atributo: `part_class_info` ### GClass (Tabla: gclasses) El modelo `GClass` representa las clases de clasificación en sistemas SCAII y SCAF. #### Relaciones: 1. **Con MaterialType (public.material_types)** - Campo: `material_key` → `material_types.key` - Relación: Many-to-One - Propósito: Tipo de material de la clase 2. **Con GPart (gparts)** - Campos: `(client_key, class_code)` → `(client_key, part_class)` - Relación: One-to-Many (inversa de la relación en GPart) - Propósito: Partes que pertenecen a esta clase - Atributo: `parts` ## Esquema de Relaciones ``` GPart ├── country (Country) # País de origen ├── currency (CurrencyType) # Tipo de moneda └── part_class_info (GClass) # Información de clasificación └── material_type (MaterialType) # Tipo de material GClass ├── material_type (MaterialType) # Tipo de material └── parts (List[GPart]) # Partes que usan esta clase ``` ## Uso de las Relaciones ### En consultas: ```python # Obtener una parte con su información completa part = session.query(GPart).options( joinedload(GPart.country), joinedload(GPart.currency), joinedload(GPart.part_class_info).joinedload(GClass.material_type) ).filter( GPart.client_key == 1, GPart.part_number == "PART001" ).first() # Acceder a los datos relacionados print(f"País: {part.country.description_es}") print(f"Moneda: {part.currency.currency_name}") print(f"Clase: {part.part_class_info.description_spanish}") print(f"Material: {part.part_class_info.material_type.description}") ``` ### En DTOs: Los DTOs pueden incluir información relacionada: ```python class PartDetailResponseDTO(BaseModel): client_key: int part_number: str description_spanish: Optional[str] country_name: Optional[str] = None currency_name: Optional[str] = None class_description: Optional[str] = None material_type: Optional[str] = None ``` ## Consideraciones Técnicas 1. **Composite Foreign Keys**: La relación entre `GPart` y `GClass` usa claves foráneas compuestas que requieren `primaryjoin` personalizado. 2. **Viewonly Relationships**: Algunas relaciones están marcadas como `viewonly=True` para evitar problemas de escritura accidental. 3. **Lazy Loading**: Por defecto, las relaciones usan lazy loading. Para consultas que necesiten datos relacionados, usar `joinedload` o `selectinload`. 4. **Type Hints**: Se usan `TYPE_CHECKING` imports para evitar import circulares mientras se mantienen los type hints. ## Futuras Relaciones Potenciales relaciones adicionales que se pueden agregar: 1. **Con Sectors** (public.sectors) - para clasificación sectorial 2. **Con Transport Types** (public.transport_types) - para modo de transporte 3. **Con Customs Sections** (public.customs_sections) - para sección aduanera 4. **Relaciones con tablas subsidiarias** como `SPartes`, `QPartes`, etc.