การ Overwrite Data เฉพาะ Partition ใน BigQuery

ใน Data Warehouse ของเราโดยปกติเราก็จะโหลดข้อมูลเข้าไปเก็บเป็น Partition ไว้ เพื่อที่ตอนที่เรา Query ข้อมูลจะได้ไม่ต้องดึงข้อมูลทั้งหมดออกมา จะถึงแค่เฉพาะ Partition ที่เราต้องการเท่านั้น

ทีนี้ตอนที่เราอยากจะโหลดข้อมูลเข้า Partition นั้น ๆ เช่น ถ้าเราทำ Partition ในระดับ DAY ไว้ แล้วต้องการโหลดข้อมูลของวันที่ 2023-04-16 เข้าไป วิธีที่ง่ายที่สุดคือ

  1. เราก็ลบข้อมูลใน Partition ของวันที่ 2023-04-16 ทิ้งก่อน
  2. แล้วก็โหลดข้อมูลใหม่ของวันที่ 2023-04-16 เข้าไปแทน

ก็เป็นอันเสร็จ แต่จะเห็นว่าเราอาจจะต้องดูแลโค้ดของเรา 2 ที่ด้วยกันคือ ส่วนลบข้อมูล กับส่วนโหลดข้อมูลเข้าไป และด้วยความดีงามของ BigQuery ที่มีสิ่งที่เรียกว่า Partition Decorators ทำให้เราไม่ต้องเขียนโค้ดทั้งลบ และโหลดแล้ว เราสามารถที่จะทำประมาณนี้ได้เลย

job_config = bigquery.LoadJobConfig(
    skip_leading_rows=1,
    write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE,
    time_partitioning=bigquery.TimePartitioning(
        type_=bigquery.TimePartitioningType.DAY,
        field="created_at",
    ),
)

...

dt = "2023-04-16"
file_path = f"{dt}-users.csv"
with open(file_path, "rb") as f:
    partition = dt.replace("-", "")
    table_id = f"my_project.hello.users${partition}"
    job = client.load_table_from_file(f, table_id, job_config=job_config)
    job.result()

ในโค้ดตัวอย่างด้านบนที่ Job Configuration จะตั้งค่า write_disposition เป็น bigquery.WriteDisposition.WRITE_TRUNCATE เพื่อบอก BigQuery ว่าเราต้องการที่จะลบข้อมูลทิ้งนะ แล้วก็กำหนดให้ทำ Partition ในระดับ DAY ที่ฟิลด์ created_at

เสร็จแล้วตรงส่วนที่กำหนด table_id ตอนจะโหลดข้อมูล จะมีการใส่ $20201207 ไว้ตามหลังตารางที่ชื่อ my_project.hello.users ก็จะทำให้ BigQuery รู้ว่าเราต้องการที่จะโหลดข้อมูลเข้าไปที่ Partition ของวันที่ 2023-04-16

เท่านี้ในการ Overwrite ข้อมูลเข้าเฉพาะ Partition นั้น ๆ เราก็ไม่ต้องเขียนโค้ดทั้งลบ และโหลดข้อมูลล่ะ :smile: