Skip to content

Commit bfd4de4

Browse files
authored
Ability to exclude some tables / some databases (bakwc#22)
1 parent fd25667 commit bfd4de4

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,24 @@ binlog_replicator:
122122
databases: 'database_name_pattern_*'
123123
tables: '*'
124124

125+
exclude_databases: ['database_10', 'database_*_42'] # optional
126+
exclude_tables: ['meta_table_*'] # optional
127+
125128
log_level: 'info' # optional
126129
```
127130
131+
#### Required settings
128132
129133
- `mysql` MySQL connection settings
130134
- `clickhouse` ClickHouse connection settings
131135
- `binlog_replicator.data_dir` Create a new empty directory, it will be used by script to store it's state
132136
- `databases` Databases name pattern to replicate, e.g. `db_*` will match `db_1` `db_2` `db_test`, list is also supported
133-
- `tables` (__optional__) - tables to filter, list is also supported
134-
- `log_level` (__optional__) - log level, default is `info`, you can set to `debug` to get maximum information (allowed values are `debug`, `info`, `warning`, `error`, `critical`)
137+
138+
#### Optional settings
139+
- `tables` - tables to filter, list is also supported
140+
- `exclude_databases` - databases to __exclude__, string or list, eg `'table1*'` or `['table2', 'table3*']`. If same database matches `databases` and `exclude_databases`, exclude has higher priority.
141+
- `exclude_tables` - databases to __exclude__, string or list. If same table matches `tables` and `exclude_tables`, exclude has higher priority.
142+
- `log_level` - log level, default is `info`, you can set to `debug` to get maximum information (allowed values are `debug`, `info`, `warning`, `error`, `critical`)
135143

136144
Few more tables / dbs examples:
137145

mysql_ch_replicator/config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ def __init__(self):
8888
self.binlog_replicator = BinlogReplicatorSettings()
8989
self.databases = ''
9090
self.tables = '*'
91+
self.exclude_databases = ''
92+
self.exclude_tables = ''
9193
self.settings_file = ''
9294
self.log_level = 'info'
9395
self.debug_log_level = False
@@ -101,6 +103,8 @@ def load(self, settings_file):
101103
self.clickhouse = ClickhouseSettings(**data['clickhouse'])
102104
self.databases = data['databases']
103105
self.tables = data.get('tables', '*')
106+
self.exclude_databases = data.get('exclude_databases', '')
107+
self.exclude_tables = data.get('exclude_tables', '')
104108
self.log_level = data.get('log_level', 'info')
105109
assert isinstance(self.databases, str) or isinstance(self.databases, list)
106110
assert isinstance(self.tables, str) or isinstance(self.tables, list)
@@ -121,9 +125,13 @@ def is_pattern_matches(cls, substr, pattern):
121125
raise ValueError()
122126

123127
def is_database_matches(self, db_name):
128+
if self.exclude_databases and self.is_pattern_matches(db_name, self.exclude_databases):
129+
return False
124130
return self.is_pattern_matches(db_name, self.databases)
125131

126132
def is_table_matches(self, table_name):
133+
if self.exclude_tables and self.is_pattern_matches(table_name, self.exclude_tables):
134+
return False
127135
return self.is_pattern_matches(table_name, self.tables)
128136

129137
def validate_log_level(self):

test_mysql_ch_replicator.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,43 @@ def test_database_tables_filtering():
406406
)
407407

408408
mysql.drop_database('test_db_3')
409+
mysql.drop_database('test_db_12')
410+
409411
mysql.create_database('test_db_3')
412+
mysql.create_database('test_db_12')
413+
410414
ch.drop_database('test_db_3')
415+
ch.drop_database('test_db_12')
411416

412417
prepare_env(cfg, mysql, ch, db_name='test_db_2')
413418

419+
mysql.execute(f'''
420+
CREATE TABLE test_table_15 (
421+
id int NOT NULL AUTO_INCREMENT,
422+
name varchar(255),
423+
age int,
424+
PRIMARY KEY (id)
425+
);
426+
''')
427+
428+
mysql.execute(f'''
429+
CREATE TABLE test_table_142 (
430+
id int NOT NULL AUTO_INCREMENT,
431+
name varchar(255),
432+
age int,
433+
PRIMARY KEY (id)
434+
);
435+
''')
436+
437+
mysql.execute(f'''
438+
CREATE TABLE test_table_143 (
439+
id int NOT NULL AUTO_INCREMENT,
440+
name varchar(255),
441+
age int,
442+
PRIMARY KEY (id)
443+
);
444+
''')
445+
414446
mysql.execute(f'''
415447
CREATE TABLE test_table_3 (
416448
id int NOT NULL AUTO_INCREMENT,
@@ -437,14 +469,20 @@ def test_database_tables_filtering():
437469

438470
assert_wait(lambda: 'test_db_2' in ch.get_databases())
439471
assert 'test_db_3' not in ch.get_databases()
472+
assert 'test_db_12' not in ch.get_databases()
440473

441474
ch.execute_command('USE test_db_2')
442475

443476
assert_wait(lambda: 'test_table_2' in ch.get_tables())
444477
assert_wait(lambda: len(ch.select('test_table_2')) == 1)
445478

479+
assert_wait(lambda: 'test_table_143' in ch.get_tables())
480+
446481
assert 'test_table_3' not in ch.get_tables()
447482

483+
assert 'test_table_15' not in ch.get_tables()
484+
assert 'test_table_142' not in ch.get_tables()
485+
448486

449487
def test_datetime_exception():
450488
cfg = config.Settings()

tests_config_databases_tables.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ binlog_replicator:
1818
databases: ['test_db_1*', 'test_db_2']
1919
tables: ['test_table_1*', 'test_table_2']
2020

21+
exclude_databases: ['test_db_12']
22+
exclude_tables: ['test_table_15', 'test_table_*42']
23+
2124
log_level: 'debug'

0 commit comments

Comments
 (0)