Restore PostgreSQL database using pg_restore.
(dump_file: Path)
| 125 | |
| 126 | |
| 127 | def _restore_postgresql(dump_file: Path) -> None: |
| 128 | """Restore PostgreSQL database using pg_restore.""" |
| 129 | logger.info("[PG_RESTORE] Starting pg_restore...") |
| 130 | logger.info(f"[PG_RESTORE] Dump file: {dump_file}") |
| 131 | |
| 132 | # Drop and recreate schema to ensure a completely clean restore |
| 133 | _clean_postgresql_schema() |
| 134 | |
| 135 | pg_args = _get_pg_args() |
| 136 | logger.info(f"[PG_RESTORE] Connection args: {pg_args}") |
| 137 | |
| 138 | cmd = [ |
| 139 | "pg_restore", |
| 140 | "--no-owner", # Skip ownership commands (we already created schema) |
| 141 | *pg_args, |
| 142 | "-v", # Verbose |
| 143 | str(dump_file), |
| 144 | ] |
| 145 | |
| 146 | logger.info(f"[PG_RESTORE] Running command: {' '.join(cmd)}") |
| 147 | |
| 148 | result = subprocess.run( |
| 149 | cmd, |
| 150 | env=_get_pg_env(), |
| 151 | capture_output=True, |
| 152 | text=True, |
| 153 | ) |
| 154 | |
| 155 | logger.info(f"[PG_RESTORE] Return code: {result.returncode}") |
| 156 | |
| 157 | # pg_restore may return non-zero even on partial success |
| 158 | # Check for actual errors vs warnings |
| 159 | if result.returncode != 0: |
| 160 | # Some errors during restore are expected (e.g., "does not exist" when cleaning) |
| 161 | # Only fail on critical errors |
| 162 | stderr = result.stderr.lower() |
| 163 | if "fatal" in stderr or "could not connect" in stderr: |
| 164 | logger.error(f"[PG_RESTORE] Failed critically: {result.stderr}") |
| 165 | raise RuntimeError(f"pg_restore failed: {result.stderr}") |
| 166 | else: |
| 167 | logger.warning(f"[PG_RESTORE] Completed with warnings: {result.stderr[:500]}...") |
| 168 | |
| 169 | logger.info("[PG_RESTORE] Completed successfully") |
| 170 | |
| 171 | |
| 172 | def _dump_sqlite(output_file: Path) -> None: |
no test coverage detected