|
1 | 1 | import datetime |
2 | 2 | import json |
| 3 | +import os |
3 | 4 | import tempfile |
4 | 5 | import uuid |
| 6 | +import zoneinfo |
5 | 7 |
|
6 | 8 | import yaml |
7 | 9 |
|
@@ -492,6 +494,72 @@ def test_timezone_conversion(): |
492 | 494 | os.unlink(temp_config_file) |
493 | 495 |
|
494 | 496 |
|
| 497 | +def test_timezone_conversion_values(): |
| 498 | + """ |
| 499 | + Test that MySQL timestamp values are correctly preserved with timezone conversion. |
| 500 | + This test reproduces the issue from GitHub issue #177. |
| 501 | + """ |
| 502 | + config_file = 'tests/tests_config_timezone.yaml' |
| 503 | + cfg = config.Settings() |
| 504 | + cfg.load(config_file) |
| 505 | + |
| 506 | + mysql = mysql_api.MySQLApi( |
| 507 | + database=None, |
| 508 | + mysql_settings=cfg.mysql, |
| 509 | + mysql_timezone=cfg.mysql_timezone, |
| 510 | + ) |
| 511 | + |
| 512 | + ch = clickhouse_api.ClickhouseApi( |
| 513 | + database=TEST_DB_NAME, |
| 514 | + clickhouse_settings=cfg.clickhouse, |
| 515 | + ) |
| 516 | + |
| 517 | + prepare_env(cfg, mysql, ch) |
| 518 | + |
| 519 | + mysql.execute(f''' |
| 520 | + CREATE TABLE `{TEST_TABLE_NAME}` ( |
| 521 | + id int NOT NULL AUTO_INCREMENT, |
| 522 | + name varchar(255), |
| 523 | + created_at timestamp NULL, |
| 524 | + updated_at timestamp(3) NULL, |
| 525 | + PRIMARY KEY (id) |
| 526 | + ); |
| 527 | + ''') |
| 528 | + |
| 529 | + mysql.execute( |
| 530 | + f"INSERT INTO `{TEST_TABLE_NAME}` (name, created_at, updated_at) " |
| 531 | + f"VALUES ('test_timezone', '2023-08-15 14:30:00', '2023-08-15 14:30:00.123');", |
| 532 | + commit=True, |
| 533 | + ) |
| 534 | + |
| 535 | + run_all_runner = RunAllRunner(cfg_file=config_file) |
| 536 | + run_all_runner.run() |
| 537 | + |
| 538 | + assert_wait(lambda: TEST_DB_NAME in ch.get_databases()) |
| 539 | + ch.execute_command(f'USE `{TEST_DB_NAME}`') |
| 540 | + assert_wait(lambda: TEST_TABLE_NAME in ch.get_tables()) |
| 541 | + assert_wait(lambda: len(ch.select(TEST_TABLE_NAME)) == 1) |
| 542 | + |
| 543 | + results = ch.select(TEST_TABLE_NAME) |
| 544 | + assert len(results) == 1 |
| 545 | + assert results[0]['name'] == 'test_timezone' |
| 546 | + |
| 547 | + created_at_value = results[0]['created_at'] |
| 548 | + updated_at_value = results[0]['updated_at'] |
| 549 | + |
| 550 | + expected_dt = datetime.datetime(2023, 8, 15, 14, 30, 0) |
| 551 | + ny_tz = zoneinfo.ZoneInfo('America/New_York') |
| 552 | + expected_dt_with_tz = expected_dt.replace(tzinfo=ny_tz) |
| 553 | + |
| 554 | + assert created_at_value == expected_dt_with_tz, f"Expected {expected_dt_with_tz}, got {created_at_value}" |
| 555 | + |
| 556 | + expected_dt_with_microseconds = datetime.datetime(2023, 8, 15, 14, 30, 0, 123000) |
| 557 | + expected_dt_with_microseconds_tz = expected_dt_with_microseconds.replace(tzinfo=ny_tz) |
| 558 | + assert updated_at_value == expected_dt_with_microseconds_tz, f"Expected {expected_dt_with_microseconds_tz}, got {updated_at_value}" |
| 559 | + |
| 560 | + run_all_runner.stop() |
| 561 | + |
| 562 | + |
495 | 563 | def test_year_type(): |
496 | 564 | """ |
497 | 565 | Test that MySQL YEAR type is properly converted to UInt16 in ClickHouse |
|
0 commit comments