165 lines
6.4 KiB
Python
165 lines
6.4 KiB
Python
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() |