Initial commit: Sistema Autoparts DB

- Base de datos SQLite con información de vehículos
- Dashboard web con Flask y Bootstrap
- Scripts de web scraping para RockAuto
- Interfaz CLI para consultas
- Documentación completa del proyecto

Incluye:
- 12 marcas de vehículos
- 10,923 modelos
- 10,919 especificaciones de motores
- 12,075 combinaciones modelo-año-motor
This commit is contained in:
2026-01-19 08:45:03 +00:00
commit f395d67136
59 changed files with 10881 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
# Vehicle Database - Getting Started Guide
## Overview
This project provides a comprehensive database system for storing information about vehicle brands, models, years, and engines. The database is built using SQLite and managed through Python scripts.
## Database Structure
The database consists of five main tables:
- **brands**: Vehicle manufacturers (Toyota, Ford, etc.)
- **models**: Vehicle models (Camry, F-150, etc.)
- **engines**: Engine specifications (2JZ-GTE, EcoBoost, etc.)
- **years**: Calendar years for vehicle production
- **model_year_engine**: Junction table linking all entities with trim levels and specifications
## Setup and Usage
### 1. Initial Setup
Run the setup script to initialize the database:
```bash
cd vehicle_database
./setup.sh
```
### 2. Querying the Database
Use the interactive query interface:
```bash
python3 scripts/query_interface.py
```
The query interface allows you to:
- Search for vehicles by brand, model, year, or engine
- Browse all available brands
- View models for specific brands
- See production years for specific models
### 3. Managing the Database
Use the database manager for programmatic access:
```bash
python3 scripts/database_manager.py
```
### 4. Importing Data
To import data from CSV files:
1. Prepare your data in the required CSV format
2. Use the CSV importer functionality in your own scripts
Sample CSV files are provided in the `data/` directory.
## Example Queries
The system supports various search options:
- Find all vehicles by a specific brand
- Search for a specific model across all years
- Filter by engine type or specifications
- Look up trim levels and drivetrain configurations
## Extending the Database
To add more data:
1. Use the Python API in `scripts/database_manager.py`
2. Directly execute SQL commands on the SQLite database
3. Import data from CSV files using the structure provided
## File Structure
```
vehicle_database/
├── sql/
│ └── schema.sql # Database schema
├── scripts/
│ ├── database_manager.py # Main database manager
│ ├── query_interface.py # Interactive query interface
│ └── csv_importer.py # CSV import functionality
├── data/ # Sample CSV data files
├── vehicle_database.db # SQLite database file
├── setup.sh # Setup script
└── README.md # Project documentation
```
## Next Steps
1. Explore the database using the query interface
2. Add your own vehicle data
3. Customize the schema if needed for your specific requirements
4. Extend the Python scripts with additional functionality

106
vehicle_database/README.md Normal file
View File

@@ -0,0 +1,106 @@
# Vehicle Database
A comprehensive database system for storing information about vehicle brands, models, years, and engines.
## Overview
This project provides a structured database for vehicle information with the following entities:
- **Brands**: Vehicle manufacturers with details like country of origin and founding year
- **Models**: Vehicle models with body type, generation, and production years
- **Years**: Calendar years for vehicle production
- **Engines**: Engine specifications including displacement, cylinders, power, and fuel type
- **Model-Year-Engine**: Junction table linking all entities with trim levels and specifications
## Database Schema
The database uses SQLite and consists of the following tables:
### `brands`
- `id`: Primary key
- `name`: Brand name (e.g., Toyota, Ford)
- `country`: Country of origin
- `founded_year`: Year the company was founded
### `engines`
- `id`: Primary key
- `name`: Engine name
- `displacement_cc`: Engine displacement in cubic centimeters
- `cylinders`: Number of cylinders
- `fuel_type`: Type of fuel (gasoline, diesel, electric, hybrid)
- `power_hp`: Horsepower
- `torque_nm`: Torque in Newton meters
- `engine_code`: Manufacturer engine code
### `models`
- `id`: Primary key
- `brand_id`: Foreign key to brands table
- `name`: Model name (e.g., Camry, Civic)
- `body_type`: Body style (sedan, SUV, truck, etc.)
- `generation`: Model generation
- `production_start_year`: Year production started
- `production_end_year`: Year production ended (NULL if still in production)
### `years`
- `id`: Primary key
- `year`: Calendar year
### `model_year_engine`
- `id`: Primary key
- `model_id`: Foreign key to models table
- `year_id`: Foreign key to years table
- `engine_id`: Foreign key to engines table
- `trim_level`: Trim level (e.g., base, luxury, sport)
- `drivetrain`: Drive system (FWD, RWD, AWD, 4WD)
- `transmission`: Transmission type (manual, automatic, CVT)
## Setup
1. Install Python 3.x if not already installed
2. Clone or download this repository
3. Run the database manager script:
```bash
cd vehicle_database
python scripts/database_manager.py
```
This will create the database, populate it with sample data, and run example queries.
## Usage
The `VehicleDatabaseManager` class provides methods to:
- Create and manage the database schema
- Insert new brands, models, engines, and years
- Query vehicle information
- Link models, years, and engines with trim levels and specifications
## Sample Queries
The script demonstrates several query patterns:
- Get all brands
- Get models for a specific brand
- Search for specific vehicles by brand, model, year, or engine
- Retrieve comprehensive vehicle information
## Extending the Database
To add more data, you can:
1. Use the provided Python API
2. Directly execute SQL commands on the SQLite database
3. Import data from CSV files using the provided structure
## File Structure
```
vehicle_database/
├── sql/
│ └── schema.sql # Database schema
├── scripts/
│ └── database_manager.py # Python database manager
├── data/ # Directory for data files
└── README.md # This file
```

View File

@@ -0,0 +1,6 @@
name,country,founded_year
Mercedes-Benz,Germany,1926
Audi,Germany,1909
Nissan,Japan,1933
Chevrolet,USA,1911
Volkswagen,Germany,1937
1 name country founded_year
2 Mercedes-Benz Germany 1926
3 Audi Germany 1909
4 Nissan Japan 1933
5 Chevrolet USA 1911
6 Volkswagen Germany 1937

View File

@@ -0,0 +1,5 @@
name,displacement_cc,cylinders,fuel_type,power_hp,torque_nm,engine_code
VQ35DE,3500,6,gasoline,280,260,VQ35DE
LS3,6200,8,gasoline,430,424,LS3
EA888,2000,4,gasoline,228,258,EA888
M274,2000,4,gasoline,241,273,M274
1 name displacement_cc cylinders fuel_type power_hp torque_nm engine_code
2 VQ35DE 3500 6 gasoline 280 260 VQ35DE
3 LS3 6200 8 gasoline 430 424 LS3
4 EA888 2000 4 gasoline 228 258 EA888
5 M274 2000 4 gasoline 241 273 M274

View File

@@ -0,0 +1,5 @@
brand_name,name,body_type,generation,production_start_year,production_end_year
Toyota,Corolla,sedan,E210,2018,
Honda,Accord,sedan,X,2018,
Ford,F-150,truck,13th Gen,2015,
BMW,3 Series,sedan,G20,2018,
1 brand_name name body_type generation production_start_year production_end_year
2 Toyota Corolla sedan E210 2018
3 Honda Accord sedan X 2018
4 Ford F-150 truck 13th Gen 2015
5 BMW 3 Series sedan G20 2018

View File

@@ -0,0 +1,152 @@
#!/usr/bin/env python3
"""
CSV Import Script for Vehicle Database
This script allows importing vehicle data from CSV files
"""
import csv
import sqlite3
import os
from typing import Dict, List
class CSVImporter:
def __init__(self, db_path: str = "vehicle_database.db"):
self.db_path = db_path
def import_brands_from_csv(self, csv_file: str):
"""Import brands from a CSV file"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
with open(csv_file, 'r', newline='', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
cursor.execute(
"INSERT OR IGNORE INTO brands (name, country, founded_year) VALUES (?, ?, ?)",
(row['name'], row.get('country'), row.get('founded_year'))
)
conn.commit()
conn.close()
print(f"Imported brands from {csv_file}")
def import_engines_from_csv(self, csv_file: str):
"""Import engines from a CSV file"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
with open(csv_file, 'r', newline='', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
cursor.execute(
"""INSERT OR IGNORE INTO engines
(name, displacement_cc, cylinders, fuel_type, power_hp, torque_nm, engine_code)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(
row['name'],
row.get('displacement_cc'),
row.get('cylinders'),
row.get('fuel_type'),
row.get('power_hp'),
row.get('torque_nm'),
row.get('engine_code')
)
)
conn.commit()
conn.close()
print(f"Imported engines from {csv_file}")
def import_models_from_csv(self, csv_file: str):
"""Import models from a CSV file"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
with open(csv_file, 'r', newline='', encoding='utf-8') as file:
reader = csv.DictReader(file)
# First, create a mapping of brand names to IDs
cursor.execute("SELECT id, name FROM brands")
brand_map = {row[1]: row[0] for row in cursor.fetchall()}
for row in reader:
brand_id = brand_map.get(row['brand_name'])
if brand_id is None:
print(f"Warning: Brand '{row['brand_name']}' not found in database")
continue
cursor.execute(
"""INSERT OR IGNORE INTO models
(brand_id, name, body_type, generation, production_start_year, production_end_year)
VALUES (?, ?, ?, ?, ?, ?)""",
(
brand_id,
row['name'],
row.get('body_type'),
row.get('generation'),
row.get('production_start_year'),
row.get('production_end_year')
)
)
conn.commit()
conn.close()
print(f"Imported models from {csv_file}")
def create_sample_csv_files(self):
"""Create sample CSV files with example data"""
os.makedirs("data", exist_ok=True)
# Sample brands CSV
with open("data/brands.csv", "w", newline="", encoding="utf-8") as csvfile:
fieldnames = ["name", "country", "founded_year"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows([
{"name": "Mercedes-Benz", "country": "Germany", "founded_year": 1926},
{"name": "Audi", "country": "Germany", "founded_year": 1909},
{"name": "Nissan", "country": "Japan", "founded_year": 1933},
{"name": "Chevrolet", "country": "USA", "founded_year": 1911},
{"name": "Volkswagen", "country": "Germany", "founded_year": 1937}
])
# Sample engines CSV
with open("data/engines.csv", "w", newline="", encoding="utf-8") as csvfile:
fieldnames = ["name", "displacement_cc", "cylinders", "fuel_type", "power_hp", "torque_nm", "engine_code"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows([
{"name": "VQ35DE", "displacement_cc": 3500, "cylinders": 6, "fuel_type": "gasoline", "power_hp": 280, "torque_nm": 260, "engine_code": "VQ35DE"},
{"name": "LS3", "displacement_cc": 6200, "cylinders": 8, "fuel_type": "gasoline", "power_hp": 430, "torque_nm": 424, "engine_code": "LS3"},
{"name": "EA888", "displacement_cc": 2000, "cylinders": 4, "fuel_type": "gasoline", "power_hp": 228, "torque_nm": 258, "engine_code": "EA888"},
{"name": "M274", "displacement_cc": 2000, "cylinders": 4, "fuel_type": "gasoline", "power_hp": 241, "torque_nm": 273, "engine_code": "M274"}
])
# Sample models CSV
with open("data/models.csv", "w", newline="", encoding="utf-8") as csvfile:
fieldnames = ["brand_name", "name", "body_type", "generation", "production_start_year", "production_end_year"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows([
{"brand_name": "Toyota", "name": "Corolla", "body_type": "sedan", "generation": "E210", "production_start_year": 2018, "production_end_year": None},
{"brand_name": "Honda", "name": "Accord", "body_type": "sedan", "generation": "X", "production_start_year": 2018, "production_end_year": None},
{"brand_name": "Ford", "name": "F-150", "body_type": "truck", "generation": "13th Gen", "production_start_year": 2015, "production_end_year": None},
{"brand_name": "BMW", "name": "3 Series", "body_type": "sedan", "generation": "G20", "production_start_year": 2018, "production_end_year": None}
])
print("Sample CSV files created in data/ directory")
def main():
importer = CSVImporter()
# Create sample CSV files
importer.create_sample_csv_files()
# Import sample data (these would be imported by the main script, but showing the functionality)
print("CSV import functionality created. Sample CSV files are in the data/ directory.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,323 @@
#!/usr/bin/env python3
"""
Vehicle Database Manager
A script to initialize and manage the vehicle database with brands, years, models, and engines
"""
import sqlite3
import os
from datetime import datetime
from typing import List, Tuple
class VehicleDatabaseManager:
def __init__(self, db_path: str = "vehicle_database.db"):
self.db_path = db_path
self.connection = None
def connect(self):
"""Connect to the SQLite database"""
self.connection = sqlite3.connect(self.db_path)
self.connection.row_factory = sqlite3.Row # Enable column access by name
print(f"Connected to database: {self.db_path}")
def disconnect(self):
"""Close the database connection"""
if self.connection:
self.connection.close()
print("Disconnected from database")
def create_tables(self, schema_file: str = "sql/schema.sql"):
"""Create tables from schema file"""
if not os.path.exists(schema_file):
raise FileNotFoundError(f"Schema file not found: {schema_file}")
with open(schema_file, 'r') as f:
schema = f.read()
if self.connection:
cursor = self.connection.cursor()
cursor.executescript(schema)
self.connection.commit()
print("Tables created successfully")
def insert_brand(self, name: str, country: str = None, founded_year: int = None) -> int:
"""Insert a new brand and return its ID"""
cursor = self.connection.cursor()
cursor.execute(
"INSERT OR IGNORE INTO brands (name, country, founded_year) VALUES (?, ?, ?)",
(name, country, founded_year)
)
self.connection.commit()
# Return the ID of the inserted or existing brand
cursor.execute("SELECT id FROM brands WHERE name = ?", (name,))
return cursor.fetchone()[0]
def insert_engine(self, name: str, displacement_cc: float = None, cylinders: int = None,
fuel_type: str = None, power_hp: int = None, torque_nm: int = None,
engine_code: str = None) -> int:
"""Insert a new engine and return its ID"""
cursor = self.connection.cursor()
cursor.execute(
"""INSERT OR IGNORE INTO engines
(name, displacement_cc, cylinders, fuel_type, power_hp, torque_nm, engine_code)
VALUES (?, ?, ?, ?, ?, ?, ?)""",
(name, displacement_cc, cylinders, fuel_type, power_hp, torque_nm, engine_code)
)
self.connection.commit()
# Return the ID of the inserted or existing engine
cursor.execute("SELECT id FROM engines WHERE name = ?", (name,))
return cursor.fetchone()[0]
def insert_model(self, brand_id: int, name: str, body_type: str = None,
generation: str = None, production_start_year: int = None,
production_end_year: int = None) -> int:
"""Insert a new model and return its ID"""
cursor = self.connection.cursor()
cursor.execute(
"""INSERT OR IGNORE INTO models
(brand_id, name, body_type, generation, production_start_year, production_end_year)
VALUES (?, ?, ?, ?, ?, ?)""",
(brand_id, name, body_type, generation, production_start_year, production_end_year)
)
self.connection.commit()
# Return the ID of the inserted or existing model
cursor.execute("SELECT id FROM models WHERE brand_id = ? AND name = ?", (brand_id, name))
return cursor.fetchone()[0]
def insert_year(self, year: int) -> int:
"""Insert a new year and return its ID"""
cursor = self.connection.cursor()
cursor.execute("INSERT OR IGNORE INTO years (year) VALUES (?)", (year,))
self.connection.commit()
# Return the ID of the inserted or existing year
cursor.execute("SELECT id FROM years WHERE year = ?", (year,))
return cursor.fetchone()[0]
def insert_model_year_engine(self, model_id: int, year_id: int, engine_id: int,
trim_level: str = None, drivetrain: str = None,
transmission: str = None):
"""Insert a model-year-engine combination"""
cursor = self.connection.cursor()
cursor.execute(
"""INSERT OR REPLACE INTO model_year_engine
(model_id, year_id, engine_id, trim_level, drivetrain, transmission)
VALUES (?, ?, ?, ?, ?, ?)""",
(model_id, year_id, engine_id, trim_level, drivetrain, transmission)
)
self.connection.commit()
def get_brands(self) -> List[Tuple]:
"""Retrieve all brands"""
cursor = self.connection.cursor()
cursor.execute("SELECT * FROM brands ORDER BY name")
return cursor.fetchall()
def get_models_by_brand(self, brand_id: int) -> List[Tuple]:
"""Retrieve all models for a specific brand"""
cursor = self.connection.cursor()
cursor.execute("""
SELECT m.*, b.name as brand_name
FROM models m
JOIN brands b ON m.brand_id = b.id
WHERE m.brand_id = ?
ORDER BY m.name
""", (brand_id,))
return cursor.fetchall()
def get_vehicle_info(self, brand_name: str = None, model_name: str = None,
year: int = None, engine_name: str = None) -> List[Tuple]:
"""Get comprehensive vehicle information based on filters"""
query = """
SELECT
b.name AS brand,
m.name AS model,
y.year,
e.name AS engine,
e.displacement_cc,
e.cylinders,
e.fuel_type,
e.power_hp,
e.torque_nm,
e.engine_code,
mye.trim_level,
mye.drivetrain,
mye.transmission
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN brands b ON m.brand_id = b.id
JOIN years y ON mye.year_id = y.id
JOIN engines e ON mye.engine_id = e.id
WHERE 1=1
"""
params = []
if brand_name:
query += " AND b.name LIKE ?"
params.append(f"%{brand_name}%")
if model_name:
query += " AND m.name LIKE ?"
params.append(f"%{model_name}%")
if year:
query += " AND y.year = ?"
params.append(year)
if engine_name:
query += " AND e.name LIKE ?"
params.append(f"%{engine_name}%")
query += " ORDER BY b.name, m.name, y.year"
cursor = self.connection.cursor()
cursor.execute(query, params)
return cursor.fetchall()
def populate_sample_data(db_manager: VehicleDatabaseManager):
"""Populate the database with sample data"""
print("Populating sample data...")
# Insert sample brands
toyota_id = db_manager.insert_brand("Toyota", "Japan", 1937)
honda_id = db_manager.insert_brand("Honda", "Japan", 1948)
ford_id = db_manager.insert_brand("Ford", "USA", 1903)
bmw_id = db_manager.insert_brand("BMW", "Germany", 1916)
# Insert sample engines
engine_2jz = db_manager.insert_engine(
"2JZ-GTE",
displacement_cc=3000,
cylinders=6,
fuel_type="gasoline",
power_hp=320,
torque_nm=450,
engine_code="2JZ-GTE"
)
engine_k20 = db_manager.insert_engine(
"K20C1",
displacement_cc=2000,
cylinders=4,
fuel_type="gasoline",
power_hp=280,
torque_nm=260,
engine_code="K20C1"
)
engine_ecoboost = db_manager.insert_engine(
"EcoBoost V6",
displacement_cc=3500,
cylinders=6,
fuel_type="gasoline",
power_hp=375,
torque_nm=470,
engine_code="EcoBoost V6"
)
engine_n52 = db_manager.insert_engine(
"N52B30",
displacement_cc=3000,
cylinders=6,
fuel_type="gasoline",
power_hp=255,
torque_nm=310,
engine_code="N52B30"
)
# Insert sample models
camry_id = db_manager.insert_model(
toyota_id,
"Camry",
body_type="sedan",
generation="XV70",
production_start_year=2017,
production_end_year=None
)
civic_id = db_manager.insert_model(
honda_id,
"Civic",
body_type="sedan",
generation="XI",
production_start_year=2016,
production_end_year=None
)
mustang_id = db_manager.insert_model(
ford_id,
"Mustang",
body_type="coupe",
generation="S550",
production_start_year=2015,
production_end_year=None
)
x3_id = db_manager.insert_model(
bmw_id,
"X3",
body_type="suv",
generation="G01",
production_start_year=2017,
production_end_year=None
)
# Insert years
year_2020 = db_manager.insert_year(2020)
year_2021 = db_manager.insert_year(2021)
year_2022 = db_manager.insert_year(2022)
# Link models, years, and engines
db_manager.insert_model_year_engine(civic_id, year_2020, engine_k20, "Sport", "FWD", "automatic")
db_manager.insert_model_year_engine(mustang_id, year_2020, engine_ecoboost, "GT", "RWD", "automatic")
db_manager.insert_model_year_engine(x3_id, year_2021, engine_n52, "xDrive30i", "AWD", "automatic")
db_manager.insert_model_year_engine(camry_id, year_2022, engine_k20, "SE", "FWD", "automatic")
print("Sample data populated successfully!")
def main():
# Initialize the database manager
db_manager = VehicleDatabaseManager()
try:
# Connect to database
db_manager.connect()
# Create tables
db_manager.create_tables()
# Populate with sample data
populate_sample_data(db_manager)
# Demonstrate queries
print("\n--- All Brands ---")
brands = db_manager.get_brands()
for brand in brands:
print(f"ID: {brand['id']}, Name: {brand['name']}, Country: {brand['country']}")
print(f"\n--- Models for Toyota (ID: {brands[0]['id']}) ---")
toyota_models = db_manager.get_models_by_brand(brands[0]['id'])
for model in toyota_models:
print(f"Model: {model['name']}, Body Type: {model['body_type']}")
print("\n--- All Vehicle Information ---")
all_vehicles = db_manager.get_vehicle_info()
for vehicle in all_vehicles:
print(f"{vehicle['brand']} {vehicle['model']} {vehicle['year']} - "
f"{vehicle['engine']} ({vehicle['power_hp']} HP)")
print("\n--- Search for Honda Civic ---")
honda_civic = db_manager.get_vehicle_info(brand_name="Honda", model_name="Civic")
for vehicle in honda_civic:
print(f"{vehicle['brand']} {vehicle['model']} {vehicle['year']} - "
f"{vehicle['engine']} ({vehicle['power_hp']} HP)")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Close the connection
db_manager.disconnect()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,193 @@
#!/usr/bin/env python3
"""
Simple Query Interface for Vehicle Database
Provides a command-line interface for searching the vehicle database
"""
import sqlite3
from typing import List, Tuple
class VehicleQueryInterface:
def __init__(self, db_path: str = "vehicle_database.db"):
self.db_path = db_path
def search_vehicles(self, brand: str = None, model: str = None, year: int = None,
engine: str = None, limit: int = 50) -> List[Tuple]:
"""Search for vehicles based on various criteria"""
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row # Enable column access by name
cursor = conn.cursor()
query = """
SELECT
b.name AS brand,
m.name AS model,
y.year,
e.name AS engine,
e.displacement_cc,
e.cylinders,
e.fuel_type,
e.power_hp,
mye.trim_level,
mye.drivetrain,
mye.transmission
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN brands b ON m.brand_id = b.id
JOIN years y ON mye.year_id = y.id
JOIN engines e ON mye.engine_id = e.id
WHERE 1=1
"""
params = []
if brand:
query += " AND b.name LIKE ?"
params.append(f"%{brand}%")
if model:
query += " AND m.name LIKE ?"
params.append(f"%{model}%")
if year:
query += " AND y.year = ?"
params.append(year)
if engine:
query += " AND e.name LIKE ?"
params.append(f"%{engine}%")
query += f" ORDER BY b.name, m.name, y.year LIMIT {limit}"
cursor.execute(query, params)
results = cursor.fetchall()
conn.close()
return results
def get_all_brands(self) -> List[Tuple]:
"""Get a list of all brands in the database"""
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT name FROM brands ORDER BY name")
results = cursor.fetchall()
conn.close()
return [row[0] for row in results]
def get_models_by_brand(self, brand_name: str) -> List[Tuple]:
"""Get all models for a specific brand"""
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("""
SELECT DISTINCT m.name
FROM models m
JOIN brands b ON m.brand_id = b.id
WHERE b.name = ?
ORDER BY m.name
""", (brand_name,))
results = cursor.fetchall()
conn.close()
return [row[0] for row in results]
def get_years_for_model(self, model_name: str) -> List[int]:
"""Get all years for a specific model"""
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("""
SELECT DISTINCT y.year
FROM model_year_engine mye
JOIN models m ON mye.model_id = m.id
JOIN years y ON mye.year_id = y.id
WHERE m.name = ?
ORDER BY y.year
""", (model_name,))
results = cursor.fetchall()
conn.close()
return [row[0] for row in results]
def main():
interface = VehicleQueryInterface()
print("Vehicle Database Query Interface")
print("=================================")
while True:
print("\nOptions:")
print("1. Search vehicles")
print("2. List all brands")
print("3. List models for a brand")
print("4. List years for a model")
print("5. Exit")
choice = input("\nEnter your choice (1-5): ").strip()
if choice == "1":
print("\nSearch for vehicles:")
brand = input("Brand (optional): ").strip() or None
model = input("Model (optional): ").strip() or None
year_input = input("Year (optional): ").strip()
year = int(year_input) if year_input else None
engine = input("Engine (optional): ").strip() or None
results = interface.search_vehicles(brand=brand, model=model, year=year, engine=engine)
if results:
print(f"\nFound {len(results)} result(s):")
print("-" * 100)
for i, vehicle in enumerate(results, 1):
print(f"{i:2d}. {vehicle['year']} {vehicle['brand']} {vehicle['model']}")
print(f" Engine: {vehicle['engine']} ({vehicle['power_hp']} HP, {vehicle['displacement_cc']} cc)")
print(f" Trim: {vehicle['trim_level']}, Drivetrain: {vehicle['drivetrain']}, Transmission: {vehicle['transmission']}")
print()
else:
print("No vehicles found matching your criteria.")
elif choice == "2":
brands = interface.get_all_brands()
print(f"\nAll brands ({len(brands)}):")
for i, brand in enumerate(brands, 1):
print(f"{i:2d}. {brand}")
elif choice == "3":
brand = input("Enter brand name: ").strip()
if brand:
models = interface.get_models_by_brand(brand)
if models:
print(f"\nModels for {brand} ({len(models)}):")
for i, model in enumerate(models, 1):
print(f"{i:2d}. {model}")
else:
print(f"No models found for brand: {brand}")
else:
print("Please enter a brand name.")
elif choice == "4":
model = input("Enter model name: ").strip()
if model:
years = interface.get_years_for_model(model)
if years:
print(f"\nYears for {model} ({len(years)}):")
for i, year in enumerate(years, 1):
print(f"{i:2d}. {year}")
else:
print(f"No years found for model: {model}")
else:
print("Please enter a model name.")
elif choice == "5":
print("Thank you for using the Vehicle Database Query Interface!")
break
else:
print("Invalid choice. Please enter 1-5.")
if __name__ == "__main__":
main()

29
vehicle_database/setup.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# Setup script for Vehicle Database
echo "Vehicle Database Setup"
echo "======================"
# Check if Python3 is available
if ! command -v python3 &> /dev/null; then
echo "Python3 is required but not installed. Please install Python3 first."
exit 1
fi
echo "Python3 is available."
# Check if the database already exists
if [ -f "vehicle_database.db" ]; then
echo "Database already exists."
else
echo "Creating new database with sample data..."
python3 scripts/database_manager.py
fi
echo ""
echo "Setup complete! Available scripts:"
echo "1. Query Interface: python3 scripts/query_interface.py"
echo "2. Database Manager: python3 scripts/database_manager.py"
echo "3. CSV Importer: python3 scripts/csv_importer.py"
echo ""
echo "To start querying the database, run: python3 scripts/query_interface.py"

View File

@@ -0,0 +1,66 @@
-- Vehicle Database Schema
-- Tables for storing vehicle information: brands, years, models, and engines
-- Table for vehicle brands/manufacturers
CREATE TABLE IF NOT EXISTS brands (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
country TEXT,
founded_year INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Table for engine specifications
CREATE TABLE IF NOT EXISTS engines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
displacement_cc REAL, -- Engine displacement in cubic centimeters
cylinders INTEGER, -- Number of cylinders
fuel_type TEXT CHECK(fuel_type IN ('gasoline', 'diesel', 'electric', 'hybrid', 'other')),
power_hp INTEGER, -- Horsepower
torque_nm INTEGER, -- Torque in Newton meters
engine_code TEXT, -- Manufacturer engine code
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Table for vehicle models
CREATE TABLE IF NOT EXISTS models (
id INTEGER PRIMARY KEY AUTOINCREMENT,
brand_id INTEGER NOT NULL,
name TEXT NOT NULL,
body_type TEXT CHECK(body_type IN ('sedan', 'hatchback', 'suv', 'truck', 'coupe', 'convertible', 'wagon', 'van', 'other')),
generation TEXT, -- Model generation (e.g., MK1, MK2)
production_start_year INTEGER,
production_end_year INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (brand_id) REFERENCES brands(id)
);
-- Table for years (to link with models)
CREATE TABLE IF NOT EXISTS years (
id INTEGER PRIMARY KEY AUTOINCREMENT,
year INTEGER NOT NULL UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Junction table to connect models, years, and engines
CREATE TABLE IF NOT EXISTS model_year_engine (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model_id INTEGER NOT NULL,
year_id INTEGER NOT NULL,
engine_id INTEGER NOT NULL,
trim_level TEXT, -- Trim level (e.g., base, luxury, sport)
drivetrain TEXT CHECK(drivetrain IN ('FWD', 'RWD', 'AWD', '4WD', 'other')),
transmission TEXT CHECK(transmission IN ('manual', 'automatic', 'CVT', 'other')),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (model_id) REFERENCES models(id),
FOREIGN KEY (year_id) REFERENCES years(id),
FOREIGN KEY (engine_id) REFERENCES engines(id),
UNIQUE(model_id, year_id, engine_id, trim_level) -- Prevent duplicate combinations
);
-- Indexes for better performance
CREATE INDEX IF NOT EXISTS idx_models_brand ON models(brand_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_model ON model_year_engine(model_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_year ON model_year_engine(year_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_engine ON model_year_engine(engine_id);

Binary file not shown.