Skip to content

Commit 566848d

Browse files
Fix database cleanup on reindex (#126)
1 parent b0ae1c8 commit 566848d

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

src/dipdup/config.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class PostgresDatabaseConfig:
7676
port: int = 5432
7777
schema_name: str = 'public'
7878
password: str = ''
79-
immune_tables: Optional[List[str]] = None
79+
immune_tables: List[str] = Field(default_factory=list)
8080

8181
@property
8282
def connection_string(self) -> str:
@@ -86,8 +86,9 @@ def connection_string(self) -> str:
8686

8787
@validator('immune_tables')
8888
def valid_immune_tables(cls, v):
89-
if v and 'dipdup_state' in v:
90-
raise ConfigurationError('`dipdup_state` table can\'t be immune')
89+
for table in v:
90+
if table.startswith('dipdup'):
91+
raise ConfigurationError('Tables with `dipdup` prefix can\'t be immune')
9192
return v
9293

9394

src/dipdup/context.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Any, Dict, Optional
55

66
from tortoise import Tortoise
7-
from tortoise.transactions import in_transaction
7+
from tortoise.transactions import get_connection
88

99
from dipdup.config import ContractConfig, DipDupConfig, IndexConfig, IndexTemplateConfig, PostgresDatabaseConfig
1010
from dipdup.datasources.datasource import Datasource
@@ -46,24 +46,30 @@ async def restart(self) -> None:
4646

4747
async def reindex(self) -> None:
4848
"""Drop all tables or whole database and restart with the same CLI arguments"""
49-
if isinstance(self.config.database, PostgresDatabaseConfig):
50-
exclude_expression = ''
51-
if self.config.database.immune_tables:
52-
immune_tables = [f"'{t}'" for t in self.config.database.immune_tables]
53-
exclude_expression = f' AND tablename NOT IN ({",".join(immune_tables)})'
54-
55-
async with in_transaction() as conn:
56-
await conn.execute_script(
57-
f'''
58-
DO $$ DECLARE
59-
r RECORD;
60-
BEGIN
61-
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema(){exclude_expression}) LOOP
62-
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
63-
END LOOP;
64-
END $$;
65-
'''
66-
)
49+
50+
async def _recreate_schema(conn, name: str) -> None:
51+
await conn.execute_script(f'DROP SCHEMA IF EXISTS {name} CASCADE')
52+
await conn.execute_script(f'CREATE SCHEMA {name}')
53+
54+
async def _move_table(conn, name: str, schema: str, new_schema: str) -> None:
55+
await conn.execute_script(f'ALTER TABLE {schema}.{name} SET SCHEMA {new_schema}')
56+
57+
database_config = self.config.database
58+
if isinstance(database_config, PostgresDatabaseConfig):
59+
conn = get_connection(None)
60+
immune_schema_name = f'{database_config.schema_name}_immune'
61+
62+
if database_config.immune_tables:
63+
await _recreate_schema(conn, immune_schema_name)
64+
65+
for table in database_config.immune_tables:
66+
await _move_table(conn, table, database_config.schema_name, immune_schema_name)
67+
68+
await _recreate_schema(conn, database_config.schema_name)
69+
70+
for table in database_config.immune_tables:
71+
await _move_table(conn, table, immune_schema_name, database_config.schema_name)
72+
6773
else:
6874
await Tortoise._drop_databases()
6975
await self.restart()

0 commit comments

Comments
 (0)