From 34459c008f2f72ab6c738d917fbde2a11399fb84 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 18 Dec 2024 19:05:34 -0600 Subject: [PATCH] fix: add `postgres.dump_db()` function --- src/wuttamess/postgres.py | 31 +++++++++++++++++++++++++++++++ tests/test_postgres.py | 10 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/wuttamess/postgres.py b/src/wuttamess/postgres.py index bc5fd49..1317768 100644 --- a/src/wuttamess/postgres.py +++ b/src/wuttamess/postgres.py @@ -152,3 +152,34 @@ def drop_db(c, name, checkfirst=True): """ if not checkfirst or db_exists(c, name): c.sudo(f'dropdb {name}', user='postgres') + + +def dump_db(c, name): + """ + Dump a PostgreSQL database to file. + + This uses the ``pg_dump`` and ``gzip`` commands to produce a + compressed SQL dump. The filename returned is based on the + ``name`` provided, e.g. ``mydbname.sql.gz``. + + :param c: Fabric connection. + + :param name: Name of the database to dump. + + :returns: Base name of the output file. We only return the + filename and not the path, since the file is expected to exist + in the connected user's home folder. + """ + sql_name = f'{name}.sql' + gz_name = f'{sql_name}.gz' + tmp_name = f'/tmp/{gz_name}' + + # TODO: when pg_dump fails the command still succeeds! (would this work?) + #cmd = f'set -e && pg_dump {name} | gzip -c > {tmp_name}' + cmd = f'pg_dump {name} | gzip -c > {tmp_name}' + + c.sudo(cmd, user='postgres') + c.run(f"cp {tmp_name} {gz_name}") + c.run(f"rm {tmp_name}") + + return gz_name diff --git a/tests/test_postgres.py b/tests/test_postgres.py index b6d0299..95e49b4 100644 --- a/tests/test_postgres.py +++ b/tests/test_postgres.py @@ -122,3 +122,13 @@ class TestDropDb(TestCase): mod.drop_db(c, 'foo') db_exists.assert_called_once_with(c, 'foo') c.sudo.assert_not_called() + + +class TestDumpDb(TestCase): + + def test_basic(self): + c = MagicMock() + result = mod.dump_db(c, 'foo') + self.assertEqual(result, 'foo.sql.gz') + c.sudo.assert_called_once_with('pg_dump foo | gzip -c > /tmp/foo.sql.gz', user='postgres') + c.run.assert_called_with('rm /tmp/foo.sql.gz')