Spaces:
Running
Running
File size: 5,259 Bytes
cd357c6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | # Foreign Key Fixes Summary
## Issue Resolved
**Error**: `Foreign key associated with column 'scm_trade_shipment.order_id' could not find table 'scm_po' with which to generate a foreign key to target column 'po_id'`
**Root Cause**:
1. Multiple `Base` instances across different model files
2. Foreign key references not including schema prefixes
3. Tables in different schemas causing reference issues
## Solutions Applied
### 1. Created Shared Database Base
**File**: `app/core/database.py`
```python
from sqlalchemy.orm import declarative_base
# Shared Base for all SQLAlchemy models
Base = declarative_base()
```
### 2. Updated All Models to Use Shared Base
#### Before:
```python
# Each model file had its own Base
from sqlalchemy.orm import declarative_base
Base = declarative_base()
```
#### After:
```python
# All models now use shared Base
from app.core.database import Base
```
**Files Updated**:
- `app/catalogues/models/model.py`
- `app/inventory/stock/models/model.py`
- `app/purchases/orders/models/model.py`
- `app/purchases/receipts/models/model.py`
- `app/trade_sales/models/model.py`
### 3. Fixed Foreign Key Schema References
#### Before:
```python
ForeignKey('scm_po.po_id')
ForeignKey('scm_grn.grn_id')
```
#### After:
```python
ForeignKey('trans.scm_po.po_id')
ForeignKey('trans.scm_grn.grn_id')
```
**Foreign Keys Fixed**:
**`app/trade_sales/models/model.py`**:
- `order_id`: `'scm_po.po_id'` β `'trans.scm_po.po_id'`
- `shipment_id`: `'scm_trade_shipment.shipment_id'` β `'trans.scm_trade_shipment.shipment_id'`
- `po_item_id`: `'scm_po_item.po_item_id'` β `'trans.scm_po_item.po_item_id'`
**`app/inventory/stock/models/model.py`**:
- `ledger_id`: `'scm_stock_ledger.ledger_id'` β `'trans.scm_stock_ledger.ledger_id'`
- `adjustment_id`: `'scm_stock_adjustment.adjustment_id'` β `'trans.scm_stock_adjustment.adjustment_id'`
**`app/purchases/orders/models/model.py`**:
- `po_id`: `'scm_po.po_id'` β `'trans.scm_po.po_id'`
**`app/purchases/receipts/models/model.py`**:
- `po_id`: `'scm_po.po_id'` β `'trans.scm_po.po_id'`
- `grn_id`: `'scm_grn.grn_id'` β `'trans.scm_grn.grn_id'`
- `po_item_id`: `'scm_po_item.po_item_id'` β `'trans.scm_po_item.po_item_id'`
- `grn_item_id`: `'scm_grn_item.grn_item_id'` β `'trans.scm_grn_item.grn_item_id'`
### 4. Updated Table Creation Logic
**File**: `app/sql.py`
#### Before:
```python
from app.purchases.orders.models.model import Base
```
#### After:
```python
from app.core.database import Base
# Import all models to ensure they're registered with Base
from app.catalogues.models.model import CatalogueRef
from app.inventory.stock.models.model import ScmStock, ScmStockLedger, ScmStockAdjustment, ScmStockTake
from app.purchases.orders.models.model import ScmPo, ScmPoItem, ScmPoStatusLog
from app.purchases.receipts.models.model import ScmGrn, ScmGrnItem, ScmGrnIssue
from app.trade_sales.models.model import ScmTradeShipment, ScmTradeShipmentItem
```
## Database Configuration
### Current Setup:
- **Database**: `cuatrolabs`
- **Schema**: `trans` (for all SCM tables)
- **Shared Base**: All models use `app.core.database.Base`
### Tables in `trans` Schema:
1. `catalogue_ref` - Catalogue reference with pricing_levels
2. `scm_stock` - Stock snapshots
3. `scm_stock_ledger` - Stock movement ledger
4. `scm_stock_adjustment` - Stock adjustments
5. `scm_stock_take` - Physical stock audits
6. `scm_po` - Purchase orders
7. `scm_po_item` - Purchase order items
8. `scm_po_status_log` - PO status changes
9. `scm_grn` - Goods receipt notes
10. `scm_grn_item` - GRN items
11. `scm_grn_issue` - GRN issues/discrepancies
12. `scm_trade_shipment` - Trade shipments
13. `scm_trade_shipment_item` - Trade shipment items
## Verification Results
### β
**All Tests Passed**:
1. **Model Import**: All models import successfully with shared Base
2. **Foreign Keys**: All foreign key relationships resolve correctly
3. **Table Creation**: `create_tables()` executes without errors
4. **Application Startup**: FastAPI app starts without foreign key errors
5. **Schema Consistency**: All tables use `trans` schema consistently
### β
**Foreign Key Relationships Working**:
- Trade shipments β Purchase orders
- Trade shipment items β PO items
- GRN items β Purchase orders
- Stock adjustments β Stock ledger
- All cross-table relationships functional
## Benefits Achieved
1. **Eliminated Foreign Key Errors**: All table relationships work correctly
2. **Schema Consistency**: All SCM tables in `trans` schema
3. **Maintainable Code**: Single shared Base for all models
4. **Database Integrity**: Proper foreign key constraints enforced
5. **Application Stability**: No startup errors related to table relationships
## Future Maintenance
### When Adding New Models:
1. Always import from `app.core.database import Base`
2. Include schema in `__table_args__ = {'schema': 'trans'}`
3. Use full schema.table format in foreign keys: `'trans.table_name.column'`
4. Add model imports to `app/sql.py` create_tables function
### Schema Migration Best Practices:
1. Use consistent schema across all related tables
2. Always specify schema explicitly in models
3. Include schema in foreign key references
4. Test foreign key relationships after schema changes |