Skip to content

Tables with multiple primary keys are breaking the replicator #30

@Stanpol

Description

@Stanpol

In the converter.py the function parse_mysql_table_structure when stumble upon the following create table statement ends up with exception:

--- processing statement:
 CREATE TABLE `test` (
  `key_a_id` bigint NOT NULL,
  `key_b_id` bigint NOT NULL,
  PRIMARY KEY (`key_a_id`, `key_b_id`),
  KEY `FK_test` (`key_b_id`),
  CONSTRAINT `test_ibfk_1` FOREIGN KEY (`key_a_id`) REFERENCES `a` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `test_ibfk_2` FOREIGN KEY (`key_b_id`) REFERENCES `b` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Exception:

=== processing line key_a_id bigint NOT NULL
=== processed line key_a_id bigint NOT NULL
=== processing line key_b_id bigint NOT NULL
=== processed line key_b_id bigint NOT NULL
=== processing line PRIMARY KEY (key_a_id ,key_b_id)
[dbrepl 2024-11-20 19:27:38,547 ERROR] unhandled exception
Traceback (most recent call last):
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/mysql_ch_replicator/db_replicator.py", line 193, in run
self.create_initial_structure()
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/mysql_ch_replicator/db_replicator.py", line 203, in create_initial_structure
self.create_initial_structure_table(table)
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/mysql_ch_replicator/db_replicator.py", line 210, in create_initial_structure_table
mysql_structure = self.converter.parse_mysql_table_structure(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/mysql_ch_replicator/converter.py", line 462, in parse_mysql_table_structure
result = pattern.parseString(line)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/pyparsing/util.py", line 256, in _inner
return fn(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.direnv/python-3.11.2/lib/python3.11/site-packages/pyparsing/core.py", line 1197, in parse_string
raise exc.with_traceback(None)
pyparsing.exceptions.ParseException: Expected ')', found ',' (at char 23), (line:1, col:24)

You probably want to try something like this to match multiple keys:

        pattern = Suppress('PRIMARY KEY (') + delimitedList(Word(alphanums + '_`')) + Suppress(')')
        try:
            result = pattern.parseString(line)
            structure.primary_keys = [strip_sql_name(col) for col in result]
        except Exception as e:
            print("Failed to parse PRIMARY KEY:", e)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions