|
24 | 24 |
|
25 | 25 | from pypaimon import CatalogFactory, Schema |
26 | 26 | from pypaimon.common.options.core_options import CoreOptions |
27 | | -from pypaimon.schema.schema_manager import SchemaManager |
| 27 | +from pypaimon.schema.data_types import AtomicType |
| 28 | +from pypaimon.schema.schema_change import SchemaChange |
28 | 29 |
|
29 | 30 |
|
30 | 31 | class SimpleTableTest(unittest.TestCase): |
@@ -492,107 +493,59 @@ def test_tag_rename_and_scan(self): |
492 | 493 | self.assertEqual(result_sorted.column('v').to_pylist(), expected.column('v').to_pylist()) |
493 | 494 |
|
494 | 495 | def test_schema_evolution_tag_read(self): |
495 | | - # schema 0 |
496 | 496 | pa_schema = pa.schema([ |
497 | 497 | ('user_id', pa.int64()), |
498 | 498 | ('item_id', pa.int64()), |
499 | 499 | ('dt', pa.string()) |
500 | 500 | ]) |
501 | 501 | schema = Schema.from_pyarrow_schema(pa_schema, partition_keys=['dt']) |
502 | | - self.catalog.create_table('default.test_0', schema, False) |
503 | | - table1 = self.catalog.get_table('default.test_0') |
504 | | - write_builder = table1.new_batch_write_builder() |
505 | | - # write 1 |
506 | | - table_write = write_builder.new_write() |
507 | | - table_commit = write_builder.new_commit() |
508 | | - data1 = { |
509 | | - 'user_id': [1, 2, 3, 4], |
510 | | - 'item_id': [1001, 1002, 1003, 1004], |
511 | | - 'dt': ['p1', 'p1', 'p2', 'p1'], |
512 | | - } |
513 | | - pa_table = pa.Table.from_pydict(data1, schema=pa_schema) |
514 | | - table_write.write_arrow(pa_table) |
515 | | - table_commit.commit(table_write.prepare_commit()) |
516 | | - table_write.close() |
517 | | - table_commit.close() |
518 | | - # write 2 |
519 | | - table_write = write_builder.new_write() |
520 | | - table_commit = write_builder.new_commit() |
521 | | - data1 = { |
522 | | - 'user_id': [11, 22, 33, 44], |
523 | | - 'item_id': [1001, 1002, 1003, 1004], |
524 | | - 'dt': ['p1', 'p1', 'p2', 'p1'], |
525 | | - } |
526 | | - pa_table = pa.Table.from_pydict(data1, schema=pa_schema) |
527 | | - table_write.write_arrow(pa_table) |
528 | | - table_commit.commit(table_write.prepare_commit()) |
529 | | - table_write.close() |
530 | | - table_commit.close() |
531 | | - # schema 1 add behavior column |
532 | | - pa_schema = pa.schema([ |
533 | | - ('user_id', pa.int64()), |
534 | | - ('item_id', pa.int64()), |
535 | | - ('dt', pa.string()), |
536 | | - ('behavior', pa.string()) |
537 | | - ]) |
538 | | - schema2 = Schema.from_pyarrow_schema(pa_schema, partition_keys=['dt']) |
539 | | - self.catalog.create_table('default.test_1', schema2, False) |
540 | | - table2 = self.catalog.get_table('default.test_1') |
541 | | - write_builder = table2.new_batch_write_builder() |
542 | | - # write 1 |
543 | | - table_write = write_builder.new_write() |
544 | | - table_commit = write_builder.new_commit() |
545 | | - data2 = { |
546 | | - 'user_id': [5, 6, 7, 8], |
547 | | - 'item_id': [1005, 1006, 1007, 1008], |
548 | | - 'dt': ['p2', 'p1', 'p2', 'p2'], |
549 | | - 'behavior': ['e', 'f', 'g', 'h'], |
550 | | - } |
551 | | - pa_table = pa.Table.from_pydict(data2, schema=pa_schema) |
552 | | - table_write.write_arrow(pa_table) |
553 | | - table_commit.commit(table_write.prepare_commit()) |
554 | | - table_write.close() |
555 | | - table_commit.close() |
556 | | - # write 2 |
| 502 | + name = 'default.test_schema_evolution' |
| 503 | + self.catalog.create_table(name, schema, False) |
| 504 | + table = self.catalog.get_table(name) |
| 505 | + expected = pa.Table.from_pydict({ |
| 506 | + 'user_id': [5, 6, 7, 8, 55, 66, 77, 88], |
| 507 | + 'item_id': [1005, 1006, 1007, 1008, 1005, 1006, 1007, 1008], |
| 508 | + 'dt': ["p2", "p1", "p2", "p2", "p2", "p1", "p2", "p2"] |
| 509 | + }, schema=pa_schema) |
| 510 | + write_builder = table.new_batch_write_builder() |
| 511 | + for data in (expected.slice(0, 4), expected.slice(4)): |
| 512 | + table_write = write_builder.new_write() |
| 513 | + table_commit = write_builder.new_commit() |
| 514 | + try: |
| 515 | + table_write.write_arrow(data) |
| 516 | + table_commit.commit(table_write.prepare_commit()) |
| 517 | + finally: |
| 518 | + table_write.close() |
| 519 | + table_commit.close() |
| 520 | + table.create_tag("tag2", snapshot_id=2) |
| 521 | + |
| 522 | + # Evolve the same table and write newer data beyond the tagged snapshot. |
| 523 | + self.catalog.alter_table(name, [SchemaChange.add_column('behavior', AtomicType('STRING'))]) |
| 524 | + table = self.catalog.get_table(name) |
| 525 | + self.assertEqual(table.table_schema.id, 1) |
| 526 | + write_builder = table.new_batch_write_builder() |
557 | 527 | table_write = write_builder.new_write() |
558 | 528 | table_commit = write_builder.new_commit() |
559 | | - data2 = { |
560 | | - 'user_id': [55, 66, 77, 88], |
561 | | - 'item_id': [1005, 1006, 1007, 1008], |
562 | | - 'dt': ['p2', 'p1', 'p2', 'p2'], |
563 | | - 'behavior': ['e', 'f', 'g', 'h'], |
564 | | - } |
565 | | - pa_table = pa.Table.from_pydict(data2, schema=pa_schema) |
566 | | - table_write.write_arrow(pa_table) |
567 | | - table_commit.commit(table_write.prepare_commit()) |
568 | | - table_write.close() |
569 | | - table_commit.close() |
| 529 | + try: |
| 530 | + table_write.write_arrow(pa.Table.from_pydict({ |
| 531 | + 'user_id': [99], |
| 532 | + 'item_id': [1009], |
| 533 | + 'dt': ['p3'], |
| 534 | + 'behavior': ['new'], |
| 535 | + }, schema=pa_schema.append(pa.field('behavior', pa.string())))) |
| 536 | + table_commit.commit(table_write.prepare_commit()) |
| 537 | + finally: |
| 538 | + table_write.close() |
| 539 | + table_commit.close() |
570 | 540 |
|
571 | | - # Create tag at snapshot 2 |
572 | | - table1.create_tag("tag2", snapshot_id=2) |
573 | | - table2.create_tag("tag2", snapshot_id=2) |
574 | | - # When table2 read tag2, it will access table1's schema |
575 | | - table2.schema_manager = SchemaManager(table2.file_io, table1.table_path) |
576 | | - table_with_tag = table2.copy({CoreOptions.SCAN_TAG_NAME.key(): "tag2"}) |
| 541 | + table_with_tag = table.copy({CoreOptions.SCAN_TAG_NAME.key(): "tag2"}) |
| 542 | + self.assertEqual(table_with_tag.table_schema.id, 0) |
577 | 543 | read_builder = table_with_tag.new_read_builder() |
578 | 544 | table_scan = read_builder.new_scan() |
579 | 545 | table_read = read_builder.new_read() |
580 | 546 |
|
581 | 547 | result = table_read.to_arrow(table_scan.plan().splits()) |
582 | 548 |
|
583 | | - self.assertEqual(result.num_rows, 8) |
584 | | - |
585 | | - expected_schema = pa.schema([ |
586 | | - ('user_id', pa.int64()), |
587 | | - ('item_id', pa.int64()), |
588 | | - ('dt', pa.string()) |
589 | | - ]) |
590 | | - expected = pa.Table.from_pydict({ |
591 | | - 'user_id': [5, 6, 7, 8, 55, 66, 77, 88], |
592 | | - 'item_id': [1005, 1006, 1007, 1008, 1005, 1006, 1007, 1008], |
593 | | - 'dt': ["p2", "p1", "p2", "p2", "p2", "p1", "p2", "p2"] |
594 | | - }, schema=expected_schema) |
595 | | - |
596 | 549 | self.assertEqual(expected, result.sort_by('user_id')) |
597 | 550 |
|
598 | 551 | def test_table_rollback_to_snapshot(self): |
|
0 commit comments