import csv import psycopg2 from datetime import datetime # Database connection parameters DB_CONFIG = { 'host': '72.61.163.139', 'port': 5433, 'database': 'tradon', 'user': 'postgres', 'password': 'dsproject' } # CSV file path CSV_FILE = r'C:\Users\SylvainDUVERNAY\Open Squared\Production - Documents\TRADON Implementation\ITSA\Reference Data\Loaders\Vessels.csv' def import_vessels(): """Import vessel data from CSV into trade_vessel table""" print("=" * 60) print("VESSEL IMPORT PROCESS STARTED") print("=" * 60) # Initialize connection and cursor objects conn = None cursor = None try: # Connect to PostgreSQL database print(f"\n[1/4] Connecting to database...") print(f" Host: {DB_CONFIG['host']}:{DB_CONFIG['port']}") print(f" Database: {DB_CONFIG['database']}") conn = psycopg2.connect(**DB_CONFIG) cursor = conn.cursor() print(" ✓ Database connection established") # Read CSV file with UTF-8-BOM encoding to handle Excel-generated CSVs print(f"\n[2/4] Reading CSV file...") print(f" File: {CSV_FILE}") with open(CSV_FILE, 'r', encoding='utf-8-sig') as file: csv_reader = csv.DictReader(file) # Initialize counters for tracking import results insert_count = 0 skip_count = 0 print(" ✓ CSV file opened successfully") print(f"\n[3/4] Processing vessel records...") print("-" * 60) # Process each row from CSV file for row_num, row in enumerate(csv_reader, start=1): # Extract and clean vessel data from CSV row vessel_name = row['vessel_name'].strip() # Convert empty strings to None for vessel_year vessel_year = row['vessel_year'].strip() if row['vessel_year'].strip() else None # Convert empty strings and 'NULL' text to None for vessel_imo vessel_imo = row['vessel_imo'].strip() if row['vessel_imo'].strip() and row['vessel_imo'].upper() != 'NULL' else None print(f"\nRow {row_num}: Processing '{vessel_name}'") print(f" Year: {vessel_year if vessel_year else 'N/A'}") print(f" IMO: {vessel_imo if vessel_imo else 'N/A'}") # Check if vessel already exists in database to avoid duplicates cursor.execute(""" SELECT id FROM trade_vessel WHERE vessel_name = %s AND vessel_imo = %s """, (vessel_name, vessel_imo)) existing = cursor.fetchone() # Skip insertion if vessel already exists if existing: print(f" ⚠ SKIPPED - Duplicate found (ID: {existing[0]})") skip_count += 1 continue # Insert new vessel record into trade_vessel table cursor.execute(""" INSERT INTO trade_vessel (vessel_name, vessel_year, vessel_imo, active, create_date, create_uid, write_date, write_uid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING id """, ( vessel_name, # Vessel name from CSV vessel_year, # Year vessel was built vessel_imo, # IMO number (international maritime identifier) True, # Set active flag to True datetime.now(), # Record creation timestamp 1, # User ID who created the record datetime.now(), # Record last modification timestamp 1 # User ID who last modified the record )) # Get the ID of the newly inserted record new_id = cursor.fetchone()[0] # Increment insert counter and log success insert_count += 1 print(f" ✓ INSERTED successfully (New ID: {new_id})") print("-" * 60) # Commit all inserts to database print(f"\n[4/4] Committing transaction to database...") conn.commit() print(" ✓ Transaction committed successfully") # Display import summary statistics print("\n" + "=" * 60) print("IMPORT SUMMARY") print("=" * 60) print(f"✓ Records inserted: {insert_count}") print(f"⚠ Records skipped: {skip_count}") print(f" Total processed: {insert_count + skip_count}") print("=" * 60) except psycopg2.Error as e: # Rollback transaction if database error occurs print("\n" + "!" * 60) print("DATABASE ERROR") print("!" * 60) if conn: conn.rollback() print("✓ Transaction rolled back") print(f"Error details: {e}") print("!" * 60) except FileNotFoundError: # Handle case where CSV file doesn't exist print("\n" + "!" * 60) print("FILE NOT FOUND ERROR") print("!" * 60) print(f"CSV file not found: {CSV_FILE}") print("Please check the file path and try again.") print("!" * 60) except Exception as e: # Catch any other unexpected errors and rollback print("\n" + "!" * 60) print("UNEXPECTED ERROR") print("!" * 60) if conn: conn.rollback() print("✓ Transaction rolled back") print(f"Error details: {e}") print("!" * 60) finally: # Clean up database resources print(f"\n[CLEANUP] Closing database connection...") if cursor: cursor.close() print(" ✓ Cursor closed") if conn: conn.close() print(" ✓ Connection closed") print("\n" + "=" * 60) print("VESSEL IMPORT PROCESS COMPLETED") print("=" * 60 + "\n") # Execute import when script is run directly if __name__ == "__main__": import_vessels()