Delta Lake schema evolution crawl: thêm cột, đổi kiểu an toàn
Delta Lake schema evolution crawl là cách để bảng Delta nhận trường mới khi crawler bắt đầu lấy thêm dữ liệu, mà không làm hỏng các cột cũ hay đánh rơi giá trị. Câu hỏi thực tế là lô nào bị từ chối, lô nào được nhận, và lô nào được nhận nhưng âm thầm đổi dữ liệu. ProxyVN chạy thư viện deltalake thật, gửi tám lô có schema khác nhau và ghi lại từng kết quả.
Delta Lake schema evolution crawl: mục tiêu và phạm vi không lặp
Phần này chốt bài toán, đầu ra và giới hạn của lab.
Bài toán cần giải
Crawler sản phẩm chạy ổn mấy tháng. Một hôm website thêm điểm đánh giá, parser lấy thêm trường rating. Hôm khác, giá xuất hiện phần lẻ, hoặc parser hỏng ghi giá thành chuỗi có đơn vị. Bảng Delta phía sau phải quyết định: nhận, từ chối hay biến đổi. Nếu không biết trước quy tắc, lỗi chỉ lộ ra khi báo cáo sai.
Đầu ra nghiệm thu
Đầu ra là một bộ fixture tám lô, mỗi lô mang một thay đổi schema điển hình. Các thay đổi gồm thêm cột, thiếu cột, đổi kiểu sang chuỗi, đổi sang số thực, thu hẹp kiểu, cột trùng hoa thường, cột toàn null và ghi lại cả bảng. Kèm theo là bảng kết quả ghi bị từ chối hay chấp nhận, phiên bản bảng sau mỗi lô và dữ liệu thực tế đã lưu.
Ranh giới với bài Iceberg snapshot
Bài về Iceberg trong cụm này nói chuyện đọc lại đúng phiên bản bảng khi schema giữ nguyên. Ở đây phiên bản bảng chỉ là phương tiện để kiểm. Trọng tâm là schema đổi thế nào và dữ liệu có bị biến dạng hay không. Bài không so sánh hai định dạng bảng.
Giới hạn của lab
Nói rõ ngay. Lab không chạy Spark. Lab dùng thư viện deltalake 1.6.6, bản Python của delta-rs, ghi bảng Delta thật xuống đĩa. Tài liệu chính thức mô tả quy tắc theo Spark. Lab cho thấy delta-rs có chỗ cư xử khác Spark, và bài ghi rõ từng chỗ.
Thứ gì thật trong lab
Thư viện deltalake, pyarrow 26.0.1, nhật ký giao dịch, tệp Parquet, lịch sử phiên bản đều là thật. Không có máy chủ giả. Thứ khác với môi trường sản xuất là bảng nằm trên ổ cục bộ thay vì kho đối tượng, và chỉ có một người ghi.
Ai nên đọc bài này
Người nạp kết quả crawl vào Delta Lake bằng Python hoặc Spark. Người từng thấy job ghi báo lỗi schema vào lúc nửa đêm. Người chưa từng thấy lỗi nào và nên lo, vì có loại thay đổi được nhận mà không báo gì.
Delta Lake schema evolution crawl: kiểm soát thay đổi khi trường mới xuất hiện
Phần này tóm tắt quy tắc trong tài liệu chính thức.
Kiểm tra schema khi ghi
Trang Table batch reads and writes nêu Delta Lake tự kiểm tra schema của DataFrame có tương thích với bảng hay không. Mọi cột của DataFrame phải có trong bảng, nếu không sẽ có ngoại lệ. Cột có trong bảng mà DataFrame thiếu thì được đặt null.
Kiểu phải khớp
Tài liệu nêu kiểu dữ liệu của cột trong DataFrame phải khớp với kiểu trong bảng, không khớp thì ném ngoại lệ. Đây là quy tắc của Spark. Lab sẽ cho thấy delta-rs không làm đúng như vậy với một số cặp kiểu.
Không phân biệt hoa thường
Tài liệu nêu tên cột không được chỉ khác nhau ở chữ hoa chữ thường, như Foo và foo. Delta Lake giữ nguyên cách viết nhưng không phân biệt hoa thường khi lưu schema, để tránh lỗi và mất dữ liệu vì Parquet lại phân biệt.
Những thay đổi được hỗ trợ
Tài liệu nêu các thay đổi schema được hỗ trợ gồm thêm cột mới ở vị trí bất kỳ và sắp xếp lại cột. Có thể làm bằng DDL tường minh hoặc ngầm qua DML. Đổi kiểu, đổi tên hay bỏ cột thì phải ghi lại bảng.
Bật evolution khi ghi
Với Spark, tài liệu nêu tùy chọn mergeSchema trên từng lần ghi, hoặc cấu hình autoMerge cho cả phiên. Từ Delta Lake 4.3 có thêm cú pháp WITH SCHEMA EVOLUTION. Nếu đặt cả mức thao tác lẫn mức phiên, mức thao tác được ưu tiên.
Đổi kiểu bằng ghi lại bảng
Tài liệu đưa ví dụ đổi kiểu cột: đọc bảng, ép kiểu cột, ghi đè với tùy chọn overwriteSchema. Đổi tên cột cũng theo cách đó. Nghĩa là đổi kiểu là thao tác có chủ đích, không xảy ra tự động trong lúc nạp hằng ngày.
Cột kiểu null
Tài liệu nêu Parquet không hỗ trợ kiểu null, nên cột kiểu null bị bỏ khỏi dữ liệu khi ghi nhưng vẫn giữ trong schema. Khi nhận kiểu khác cho cột đó, schema được gộp sang kiểu mới. Với crawl, đây là trường hợp trường mới xuất hiện nhưng lô đầu chưa trang nào có giá trị.
Tên tham số trong deltalake
Thư viện Python dùng tham số schema_mode thay cho mergeSchema. Giá trị merge tương ứng việc gộp schema, giá trị overwrite tương ứng ghi lại schema khi chế độ ghi là overwrite. Bài dùng tên của thư viện Python vì đó là thứ lab chạy.
Delta Lake schema evolution crawl: tạo Delta table có schema ban đầu rõ
Phần này dựng bảng gốc và giải thích vì sao schema phải rõ ngay từ đầu.
Schema gốc
Bảng sản phẩm có ba cột: page_id kiểu chuỗi, price kiểu số nguyên 64 bit đơn vị đồng, crawl_run kiểu chuỗi.
import pyarrow as pa
from deltalake import write_deltalake, DeltaTable
base = pa.schema([("page_id", pa.string()), ("price", pa.int64()),
("crawl_run", pa.string())])
t0 = pa.Table.from_pylist(
[{"page_id": f"p{i}", "price": i * 100, "crawl_run": "r1"} for i in range(1, 6)],
schema=base)
write_deltalake("tbl", t0, mode="error")
Chế độ error nghĩa là báo lỗi nếu bảng đã tồn tại. Phiên bản 0 có năm dòng.
Vì sao giá là số nguyên
Giá đồng Việt Nam không có phần lẻ, số nguyên 64 bit đủ chứa mọi mức giá. Chọn số nguyên giúp so sánh và cộng dồn không có sai số làm tròn. Nhưng lựa chọn này cũng mở đường cho lỗi lab phát hiện ở phần sau, khi có giá trị có phần lẻ đi vào.
Truyền schema tường minh cho pyarrow
Đừng để pyarrow tự suy kiểu từ danh sách Python. Một lô toàn số nhỏ có thể được suy thành int64, một lô có giá trị None đầu tiên có thể thành null. Truyền schema tường minh khi dựng Table giúp lỗi xuất hiện ở bước parser, gần nguồn hơn.
Cột crawl_run làm gì
Cột crawl_run ghi lượt crawl sinh ra mỗi dòng. Khi một lô đổi schema, cột này giúp tìm ngay những dòng đến từ lô đó. Trong lab, mỗi lô có mã r1 tới r9 riêng để đối soát.
Ghi nhận phiên bản
Mỗi lần ghi thành công tăng phiên bản bảng lên một. Mã lab đọc phiên bản trước và sau mỗi lần ghi. Nếu phiên bản không đổi, lô đã bị từ chối. Nếu đổi, lô đã vào bảng, dù có thể đã bị biến đổi.
def try_write(name, tbl, **kw):
v0 = DeltaTable(p).version()
try:
write_deltalake(p, tbl, **kw)
return "CHAP NHAN", DeltaTable(p).version()
except Exception as e:
return "TU CHOI", v0, type(e).__name__
Hàm trên là bản rút gọn của mã lab.
Delta Lake schema evolution crawl: gửi batch thêm cột rồi batch đổi kiểu cột
Phần này gửi lần lượt các lô và ghi lại kết quả thật.
Lô B1: thêm cột rating
Crawler bắt đầu lấy điểm đánh giá. Lô B1 có thêm cột rating kiểu số thực. Ghi không bật evolution thì bị từ chối.
B1 them cot, khong bat evolution -> ('TU CHOI', 0, 'SchemaMismatchError: Cannot cast schema, number of fields does not match: 4 vs 3')
B1 them cot, schema_mode=merge -> ('CHAP NHAN', 1, '')
Bật schema_mode bằng merge thì lô được nhận, bảng lên phiên bản 1 với bốn cột.
Dòng cũ nhận null
Năm dòng của lượt đầu không có rating. Sau khi gộp schema, đọc lại thấy rating là giá trị rỗng. Đây đúng quy tắc trong tài liệu: cột có trong bảng mà dữ liệu thiếu thì đặt null. Báo cáo tính điểm trung bình phải loại các dòng này, nếu không sẽ hiểu sai.
Lô B2: thiếu cột crawl_run
Parser bỏ sót cột crawl_run. Tài liệu Spark nói cột thiếu được đặt null. Delta-rs trong lab lại từ chối với thông báo số trường không khớp, ba so với bốn.
B2 thieu cot crawl_run -> ('TU CHOI', 1, 'SchemaMismatchError: Cannot cast schema, number of fields does not match: 3 vs 4')
Với crawl, từ chối ở đây là điều tốt: một lô thiếu cột thường là parser hỏng, không nên lặng lẽ thành null.
Lô B3: giá thành chuỗi có đơn vị
Parser lấy nguyên văn bản hiển thị, giá thành chuỗi 1.200.000d. Lô bị từ chối, kể cả khi bật merge, với lỗi không ép được chuỗi sang Int64.
B3 price thanh string -> ('TU CHOI', 1, "Exception: Cast error: Cannot cast string '1.200.000d' to value of Int64 type")
Thông báo lỗi lộ ra một điều: delta-rs đã thử ép kiểu trước khi bỏ cuộc. Điều này dẫn tới ca tiếp theo.
Chuỗi chỉ gồm chữ số được ép ngầm

Ép kiểu ngầm
Lab gửi thêm một lô có giá là chuỗi 250000, không bật merge. Lô được nhận. Đọc lại thấy giá là số 250000, cột vẫn kiểu long.
[('p13', 250000)] Field(price, PrimitiveType("long"), nullable=True)
Không có cảnh báo nào. Nếu parser lúc trả số, lúc trả chuỗi, bảng sẽ nhận cả hai, và dấu hiệu parser không ổn định bị che đi.
Lô B4: giá thành số thực
Website bắt đầu hiển thị giá có phần lẻ, lô B4 gửi giá 999.5 kiểu float64. Lô được nhận ngay, không cần merge. Schema bảng không đổi, price vẫn là long.
B4 price thanh float64 -> ('CHAP NHAN', 2, '')
schema sau B4: [..., ('price', 'PrimitiveType("long")'), ...]
Phần lẻ bị cắt
Đọc lại dòng p9 ở phiên bản 3, giá là 999, không phải 999.5. Phần lẻ biến mất mà không có lỗi hay cảnh báo nào. Đây là ca dữ liệu mất âm thầm mà bài muốn chỉ ra. Tài liệu Spark nói kiểu không khớp thì ném ngoại lệ, còn delta-rs 1.6.6 ép kiểu và cắt.
Giá trị vượt giới hạn thì bị từ chối
Lab thử giá 1e19, vượt giới hạn số nguyên 64 bit. Lần này bị từ chối với lỗi không ép được. Vậy delta-rs ép kiểu khi giá trị nằm trong giới hạn, chỉ từ chối khi tràn. Kiểm tra dữ liệu không thể dựa vào việc ghi có báo lỗi hay không.
Lô B5: thu hẹp kiểu
Lô B5 gửi giá kiểu int32. Lô được nhận, giá trị được nới sang int64 khi lưu. Ca này an toàn vì không mất thông tin. Nó vẫn đáng ghi lại, để thấy delta-rs ép kiểu theo cả hai chiều.
Delta Lake schema evolution crawl: quan sát quy tắc cho phép và từ chối
Phần này đi qua các ca biên và gom quy tắc thành bảng.
Lô B6: cột chỉ khác hoa thường
Một parser viết Rating thay vì rating. Bật merge, lô vẫn bị từ chối vì tên cột trùng khi không phân biệt hoa thường.
B6 cot Rating hoa -> ('TU CHOI', 4, "Exception: External error: Schema error: Duplicate field name (case-insensitive): 'Rating'")
Đúng quy tắc trong tài liệu. Lỗi này tốt, vì nếu được nhận, bảng sẽ có hai cột điểm đánh giá.
Lô B7: cột mới toàn null
Website thêm trường người bán, nhưng lô đầu không trang nào có giá trị. Lô có cột seller kiểu null, bật merge, được nhận. Schema có thêm cột seller kiểu void.
B7 cot seller kieu null, merge -> ('CHAP NHAN', 5, '')
schema sau B7: [..., ('seller', 'PrimitiveType("void")')]
Kiểu void ghi vào schema là chuyện cần để ý, vì các lô sau có giá trị chuỗi sẽ phải gộp tiếp.
Bảng kết quả

Bảng tám lô
Bảng dưới là đầu ra nghiệm thu, gom từ output thật của lab.
Lô |
Thay đổi |
schema_mode |
Kết quả |
Phiên bản |
Ghi chú |
|---|---|---|---|---|---|
B1 |
Thêm cột rating |
không |
Từ chối |
0 |
Số trường 4 so với 3 |
B1 |
Thêm cột rating |
merge |
Nhận |
1 |
Dòng cũ rating null |
B2 |
Thiếu crawl_run |
không |
Từ chối |
1 |
Khác Spark |
B3 |
Giá chuỗi có đơn vị |
merge |
Từ chối |
1 |
Không ép được |
B3' |
Giá chuỗi 250000 |
không |
Nhận |
Ép ngầm sang số |
|
B4 |
Giá 999.5 |
không |
Nhận |
2 |
Lưu thành 999 |
B5 |
Giá int32 |
không |
Nhận |
4 |
Nới kiểu, an toàn |
B6 |
Cột Rating hoa |
merge |
Từ chối |
4 |
Trùng không phân biệt hoa thường |
B7 |
Cột seller null |
merge |
Nhận |
5 |
Kiểu void |
B8 |
Ghi lại, price thành chuỗi |
overwrite |
Nhận |
6 |
Đổi kiểu có chủ đích |
Ba nhóm kết quả
Nhóm từ chối gồm thêm cột không bật merge, thiếu cột, chuỗi không ép được, trùng hoa thường. Nhóm nhận đúng gồm thêm cột có merge, nới kiểu, cột null có merge. Nhóm nhận có biến đổi gồm số thực vào cột số nguyên và chuỗi số vào cột số. Nhóm thứ ba là nhóm nguy hiểm.
Merge không giúp đổi kiểu
Bật merge chỉ cho phép thêm cột. Lô B3 bật merge vẫn bị từ chối, lô B4 bật merge vẫn ghi vào cột long. Muốn đổi kiểu cột, phải ghi lại bảng có chủ đích. Đây đúng với mô tả trong tài liệu về đổi kiểu bằng ghi lại.
Khác biệt với Spark
Lab cho thấy hai chỗ delta-rs cư xử khác mô tả Spark trong tài liệu: thiếu cột bị từ chối thay vì thành null, và kiểu không khớp được ép thay vì ném ngoại lệ. Lab không chạy Spark để xác nhận Spark làm đúng như tài liệu. Ai ghi bằng cả hai engine cần thử riêng.
Khóa phiên bản thư viện
Hành vi ép kiểu là của delta-rs 1.6.6. Bản sau có thể đổi. Ghi phiên bản thư viện trong cấu hình job và chạy lại bộ fixture tám lô mỗi khi nâng cấp. Bộ fixture nhỏ, chạy vài giây, đủ để phát hiện thay đổi hành vi.
Delta Lake schema evolution crawl: đối soát schema cuối và dữ liệu không mất âm thầm
Phần này đọc lại lịch sử, đổi kiểu có chủ đích và đặt hàng rào phía trước bảng.
Lịch sử bảng
Sau B7, bảng ở phiên bản 5 với mười dòng. Lịch sử ghi một lần tạo và năm lần append.
history: [(5, 'WRITE', 'Append'), (4, 'WRITE', 'Append'), (3, 'WRITE', 'Append'),
(2, 'WRITE', 'Append'), (1, 'WRITE', 'Append'), (0, 'WRITE', 'ErrorIfExists')]
Lô bị từ chối không để lại dấu vết trong lịch sử. Muốn biết đã có bao nhiêu lô bị từ chối, job phải tự ghi log.
Schema cũ vẫn đọc được
Mở bảng ở phiên bản 0, schema vẫn là ba cột gốc và năm dòng. Thêm cột không phá phiên bản cũ. Điều này giúp so sánh trước và sau khi parser đổi, chẳng hạn kiểm số dòng có rating khác null tăng dần qua các lượt.
Lô B8: đổi kiểu có chủ đích
Giả sử quyết định chuyển giá sang chuỗi để giữ nguyên văn hiển thị. Lab đọc bảng, ép cột price sang chuỗi, ghi đè với schema_mode bằng overwrite. Bảng lên phiên bản 6, price thành kiểu chuỗi, vẫn mười dòng.
B8 overwrite + schema_mode=overwrite -> ('CHAP NHAN', 6, '')
schema sau B8: [..., ('price', 'PrimitiveType("string")'), ...] | so dong: 10
Ca này chỉ để minh họa cách đổi kiểu. Với giá, giữ số nguyên và thêm cột văn bản gốc thường hợp lý hơn.
Sau khi ghi lại, lô cũ không vào được
Gửi lại lô B3 sau B8 vẫn bị từ chối, lần này vì lô có bốn cột còn bảng có năm. Mỗi lần schema đổi, mọi producer phải cập nhật theo. Một crawler cũ còn chạy ở đâu đó sẽ bắt đầu thất bại, và đó là tín hiệu tốt.
Hàng rào trước bảng

Hàng rào trước bảng
Vì delta-rs ép kiểu ngầm, kiểm tra phải đặt trước lần ghi. Cách đơn giản: so schema của lô với schema bảng bằng pyarrow, cột nào khác kiểu thì dừng.
def guard(batch, table_path):
want = DeltaTable(table_path).schema().to_arrow()
for f in batch.schema:
i = want.get_field_index(f.name)
if i >= 0 and want.field(i).type != f.type:
raise ValueError(f"{f.name}: {f.type} khac {want.field(i).type}")
Hàm này là ví dụ triển khai, chưa xử lý cột lồng nhau.
Kiểm giá trị, không chỉ kiểu
Hàng rào kiểu bắt được giá float64 trước khi bị cắt. Nhưng nếu parser trả int64 mà giá trị sai, như bằng không cho cả lô, kiểu vẫn khớp. Cần thêm kiểm tra giá trị: tỷ lệ null, khoảng giá hợp lý, số dòng so với lượt trước.
Quy trình khi trường mới xuất hiện
Khi parser bắt đầu sinh trường mới, quy trình nên là: thêm trường vào schema mong đợi của job, chạy fixture, bật merge cho đúng lần ghi đó, kiểm schema sau ghi, rồi tắt merge lại. Bật merge thường trực làm mọi cột lạ từ parser lỗi đi thẳng vào bảng.
Đặt tên cột thống nhất
Ca B6 cho thấy một chữ hoa sai làm lô bị từ chối. Chuẩn hóa tên trường về chữ thường có gạch dưới ngay trong parser. Có danh sách tên cột được phép, cột ngoài danh sách thì dừng, thay vì để bảng quyết định.
Đối soát cuối mỗi lượt

Đối soát tổng giá
Sau mỗi lượt, đọc schema bảng, so với schema mong đợi trong mã. Đếm số dòng thêm theo crawl_run. Với cột số, so tổng hoặc giá trị lớn nhất với lô đầu vào. Ca 999.5 thành 999 sẽ lộ ra khi so tổng giá đầu vào với tổng giá đọc lại.
Delta Lake schema evolution crawl: vận hành khi nhiều crawler cùng ghi
Phần này nối kết quả lab với tình huống nhiều nguồn crawl cùng đổ vào một bảng.
Mỗi website một parser
Một bảng sản phẩm thường nhận dữ liệu từ nhiều website, mỗi website một parser. Parser của website A thêm trường rating, parser của website B chưa có. Sau khi bảng gộp schema, lô của B thiếu cột rating. Lab cho thấy delta-rs từ chối lô thiếu cột, nên mọi parser phải cập nhật cùng lúc, hoặc job ghi phải tự thêm cột rỗng.
Thêm cột rỗng có chủ đích
Thay vì để thư viện quyết định, job ghi có thể đọc schema bảng, so với lô, thêm cột còn thiếu với giá trị null đúng kiểu. Cách này giữ quy tắc trong tay anh em. Nó cũng làm rõ trong mã rằng website B chưa có điểm đánh giá, chứ không phải parser đánh rơi.
Ghi log lô bị từ chối
Lịch sử bảng chỉ ghi lần ghi thành công. Lô bị từ chối biến mất nếu job không tự ghi. Mỗi lần từ chối nên lưu lại tên lô, crawl_run, thông báo lỗi và schema của lô. Sáng hôm sau nhìn log là biết parser nào cần sửa.
Giữ lô bị từ chối
Lô bị từ chối nên được ghi ra tệp Parquet riêng trong thư mục cách ly, không xóa. Khi parser đã sửa hoặc schema đã cập nhật, nạp lại từ thư mục này thay vì crawl lại. Tiết kiệm lượt tải và giữ đúng dữ liệu của thời điểm đó.
Cột mới cần người duyệt
Không phải trường nào parser sinh ra cũng nên vào bảng. Trường chứa thông tin cá nhân của người bán, trường chứa mã theo dõi, trường rác do HTML lỗi đều có thể xuất hiện. Danh sách cột được phép giúp chặn chúng. Thêm cột vào danh sách là một bước duyệt, có người chịu trách nhiệm.
Thứ tự cột
Tài liệu nêu Delta hỗ trợ thêm cột ở vị trí bất kỳ và sắp xếp lại cột. Với dữ liệu crawl, thứ tự cột hiếm khi quan trọng, vì mọi truy vấn gọi theo tên. Đừng tốn công giữ thứ tự, hãy tốn công giữ tên và kiểu.
Báo cáo phụ thuộc cột mới
Báo cáo dùng cột rating phải biết rating chỉ có từ phiên bản 1. Ghi rõ phiên bản bắt đầu có cột trong tài liệu dữ liệu. Nếu không, người làm báo cáo sẽ tính trung bình trên cả dòng null và kết luận sai về chất lượng sản phẩm.
Thử trên bản sao trước
Mọi thay đổi schema có chủ đích, như lô B8, nên chạy trên bản sao bảng trước. Lab làm đúng như vậy khi thử ép chuỗi: sao chép thư mục bảng, khôi phục về phiên bản cần, rồi ghi thử. Bảng thật chỉ đổi khi bản sao cho kết quả đúng.
Delta Lake schema evolution crawl: đầu ra nghiệm thu và phần chưa chạy
Phần này gom tiêu chí đạt, tệp đầu ra và những gì còn phải kiểm.
Danh sách kiểm tra
Quy trình đạt khi mọi dòng dưới đây đúng.
- Schema bảng khai báo tường minh, kiểu giá chọn có chủ đích.
- Parser dựng pyarrow Table với schema tường minh.
- Có hàm chặn lô khác kiểu trước khi ghi.
- schema_mode merge chỉ bật cho lần ghi có thêm cột đã duyệt.
- Đổi kiểu cột bằng ghi lại bảng có chủ đích.
- Tên cột chuẩn hóa chữ thường trong parser.
- Mỗi lần ghi log phiên bản trước và sau, kể cả lô bị từ chối.
- Bộ fixture tám lô chạy lại mỗi khi nâng cấp thư viện.
Tệp đầu ra của lab
Lab tạo thư mục bảng Delta với bảy phiên bản, tệp ket_qua.json chứa bảng kết quả, và script kiểm tra riêng cho ca ép kiểu ngầm. Toàn bộ chạy lại bằng một lệnh trong vài giây.
Những gì lab chưa chạy
Chưa chạy Spark, chưa thử mergeSchema hay WITH SCHEMA EVOLUTION thật. Chưa thử column mapping, đổi tên cột, cột lồng nhau, ghi đồng thời, kho đối tượng. Hai khác biệt so với tài liệu là hành vi của delta-rs 1.6.6, chưa đối chiếu với bản khác.
Kiểm lại trên engine đang dùng
Nếu bảng được ghi bằng Spark, chạy cùng tám lô bằng DataFrame và so bảng kết quả. Ca B2 thiếu cột và B4 số thực là hai ca quan trọng nhất. Kết quả khác nhau giữa hai engine là lý do đủ để chỉ dùng một engine ghi cho mỗi bảng.
Proxy ở đâu trong luồng này
Proxy thuộc bước tải trang, trước khi parser sinh dữ liệu. Delta Lake nằm trong hạ tầng của anh em, không cần proxy. Với website được phép thu thập, có lúc cần IP Việt Nam để thấy đúng giá và đúng trường hiển thị trong nước. Khi đó anh em có thể mua proxy tại trang chủ ProxyVN. Vai trò proxy có ở bài Web Scraping proxy là gì, cách ghi cấu hình ở bài định dạng proxy.
Proxy và trường mới xuất hiện
Đôi khi trường mới xuất hiện vì trang trả về khác theo IP, website không hề đổi giao diện. Trang cho khách nước ngoài có thể thiếu giá hoặc thêm thông báo. Nếu một lô bỗng có cột lạ, xem log tải để biết trang được lấy qua đường nào trước khi bật merge.
Delta Lake schema evolution crawl: câu hỏi thường gặp
Các câu dưới đây gom những điểm anh em hay hỏi.
Bật merge thường trực có sao không?
Có rủi ro. Mọi cột lạ do parser hỏng sẽ đi thẳng vào bảng. Bật merge cho đúng lần ghi có cột mới đã duyệt.
Merge có đổi được kiểu cột không?
Không. Lab bật merge vẫn bị từ chối khi giá thành chuỗi có đơn vị. Đổi kiểu phải ghi lại bảng với schema_mode overwrite.
Vì sao giá 999.5 thành 999?
Delta-rs 1.6.6 ép số thực vào cột số nguyên và cắt phần lẻ, không báo lỗi. Chỉ khi giá trị vượt giới hạn mới bị từ chối. Hãy chặn lô khác kiểu trước khi ghi.
Thiếu một cột thì sao?
Trong lab, delta-rs từ chối lô thiếu cột. Tài liệu Spark mô tả cột thiếu được đặt null. Cần thử trên engine đang dùng.
Dòng cũ có giá trị gì ở cột mới?
Null. Báo cáo tính trên cột mới phải loại các dòng này, hoặc chỉ tính từ lượt crawl có cột đó.
Lô bị từ chối có làm hỏng bảng không?
Không. Lô bị từ chối không tạo phiên bản mới, bảng giữ nguyên như trước. Lab đọc phiên bản trước và sau mỗi lần ghi, lô bị từ chối không làm phiên bản tăng.
Có nên đổi giá sang số thực cho chắc?
Chỉ khi website thật sự có giá lẻ. Với giá đồng, số nguyên đủ dùng và không có sai số làm tròn. Điều cần làm là chặn lô gửi số thực vào cột số nguyên, để biết khi nào parser đổi hành vi.
Làm sao biết trước delta-rs sẽ ép kiểu?
Chạy bộ fixture trong bài với đúng phiên bản thư viện đang dùng. Lab mất vài giây. Kết quả cho biết cặp kiểu nào bị ép, cặp nào bị từ chối.
Cột kiểu void có ảnh hưởng gì?
Cột seller được ghi vào schema với kiểu void vì lô đầu toàn null. Lô sau có giá trị chuỗi cần gộp schema tiếp. Lab chưa thử bước gộp này, anh em nên thử trước khi để cột null đi vào bảng chính.
Bài có chạy Spark không?
Không. Lab chạy thư viện deltalake thật trên đĩa cục bộ. Cú pháp và quy tắc Spark lấy từ tài liệu, chưa chạy.
Delta Lake schema evolution crawl và những điều cần nhớ
Delta Lake schema evolution crawl an toàn khi anh em biết trước lô nào bị từ chối, lô nào được nhận, và lô nào được nhận nhưng dữ liệu bị đổi. Hãy chặn lô khác kiểu trước khi ghi, chỉ bật merge cho cột đã duyệt, đổi kiểu bằng ghi lại có chủ đích. Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam khuyên anh em chạy bộ fixture Delta Lake schema evolution crawl trên engine thật.