You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何批量执行DataJoint事务?Python航空预订项目需求

Hey there! Since you're new to DataJoint and need to scale up to 30k+ reservation records while hitting that 75% flight occupancy requirement, let's walk through this step by step. First, we'll fix a small bug in your current reservation logic, then build efficient batch tools to meet your project goals.

1. Fix the Core Reservation Logic (Critical Bug!)

Looking at your existing reserve function, there's a key issue: your available seats query doesn't actually filter by flight route or departure time. Right now it's pulling every unreserved seat across all flights, which isn't what you want. Let's fix that first with a corrected single-reservation function:

def reserve_single(passenger_id, origin_code, dest_code, departure_start, departure_end):
    with dj.conn().transaction:
        # First, target flights matching origin, destination, and departure window
        target_flights = Flight & {
            'origin_code': origin_code,
            'dest_code': dest_code,
            'departure': ['between', departure_start, departure_end]
        }
        
        # Get only seats on these flights that haven't been reserved yet
        available_seats = (Seat * target_flights - Reservation).fetch(as_dict=True)
        
        if not available_seats:
            raise IndexError(
                f"No seats available for flights from {origin_code} to {dest_code} between {departure_start} and {departure_end}"
            )
        
        # Pick a random available seat/flight combo
        selected = random.choice(available_seats)
        # Fetch passenger name for confirmation
        name = (Passenger & {'passenger_id': passenger_id}).fetch1('full_name')
        
        print(
            f"Success: Reserved seat {selected['aircraft_seat']} on flight {selected['flight_no']} for {name} (price: ${selected['economy_price']})"
        )
        
        # Insert the reservation (cleaner explicit fields)
        Reservation.insert1({
            'flight_no': selected['flight_no'],
            'aircraft_seat': selected['aircraft_seat'],
            'passenger_id': passenger_id
        }, ignore_extra_fields=True)

2. Batch Reservation Function for Random Bookings

If you want to generate random bulk reservations (e.g., 50 at a time), here's a function that handles this efficiently. It uses a single transaction for the batch to reduce database overhead, and skips failed attempts (no seats available) instead of rolling back the entire batch:

import random
from faker import Faker

fake = Faker()

def batch_reserve(num_bookings, origin_range=(1,7), dest_range=(1,7)):
    # Set departure window to the current month (adjust if needed)
    departure_start = fake.date_time_this_month(before_now=False).replace(day=1, hour=0, minute=0)
    departure_end = departure_start.replace(day=28, hour=23, minute=59)
    
    # Get all existing passenger IDs to sample from
    all_passengers = Passenger.fetch('passenger_id')
    if len(all_passengers) < num_bookings:
        raise ValueError("Not enough passengers in the Passenger table for this batch size")
    
    successful = 0
    failed = 0
    
    with dj.conn().transaction:
        for _ in range(num_bookings):
            try:
                # Pick random passenger, origin, and destination (ensure origin != dest)
                p_id = random.choice(all_passengers)
                origin = random.randint(*origin_range)
                dest = random.randint(*dest_range)
                while origin == dest:
                    dest = random.randint(*dest_range)
                
                # Use our corrected single reservation function
                reserve_single(p_id, origin, dest, departure_start, departure_end)
                successful += 1
            except IndexError:
                failed += 1
                continue
    
    print(f"Batch complete: {successful} successful bookings, {failed} failed (no seats available)")
    return successful, failed

# Example: Run a batch of 50 reservations
batch_reserve(50)

3. Guaranteed 75% Occupancy per Flight (Best for Project Requirements)

Since your project requires at least 75% occupancy per flight (108 seats per 144-seat aircraft), the most reliable way is to directly fill each flight to its target capacity. This method is far faster than random batches because it uses bulk inserts instead of individual transactions:

def fill_flight_to_capacity(flight_no, target_occupancy=0.75):
    total_seats = len(Seat.fetch())  # Should equal 144 in your setup
    target_bookings = int(total_seats * target_occupancy)
    
    # Check current reservations for this flight
    current_bookings = len((Reservation & {'flight_no': flight_no}).fetch())
    needed_bookings = target_bookings - current_bookings
    
    if needed_bookings <= 0:
        print(f"Flight {flight_no} already meets occupancy: {current_bookings}/{total_seats}")
        return
    
    # Get all available seats for this flight
    available_seats = (Seat * (Flight & {'flight_no': flight_no}) - Reservation).fetch('aircraft_seat')
    if len(available_seats) < needed_bookings:
        needed_bookings = len(available_seats)
        print(f"Flight {flight_no} has limited seats available - filling all {needed_bookings}")
    
    # Sample random passengers for the needed bookings
    selected_passengers = random.sample(Passenger.fetch('passenger_id'), needed_bookings)
    
    with dj.conn().transaction:
        # Prepare bulk insert data (list of dictionaries)
        bulk_reservations = []
        for seat, p_id in zip(available_seats[:needed_bookings], selected_passengers):
            bulk_reservations.append({
                'flight_no': flight_no,
                'aircraft_seat': seat,
                'passenger_id': p_id
            })
        
        # Bulk insert all reservations at once (way faster than individual inserts)
        Reservation.insert(bulk_reservations, ignore_extra_fields=True)
    
    new_occupancy = current_bookings + needed_bookings
    print(f"Flight {flight_no} updated: {new_occupancy}/{total_seats} ({new_occupancy/total_seats*100:.1f}% occupancy)")

# Run this for all 315 flights to hit your 30k+ reservation goal
for flight_no in range(315):
    fill_flight_to_capacity(flight_no)

4. Quick Performance Tips for DataJoint

  • Bulk Inserts: Always use Reservation.insert() with a list of entries instead of looping insert1 - this cuts down on database round trips drastically.
  • Transaction Scope: Grouping multiple inserts into a single transaction (like we did for each flight) ensures data consistency and speeds up operations.
  • Filter Early: Narrow down your flight/seat queries before joining tables (e.g., target_flights first) to avoid unnecessary data processing.

内容的提问来源于stack exchange,提问作者DONALD DAY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:24:37