Add drive-sync feature: db push/pull local-db backups to Google Drive#4
Add drive-sync feature: db push/pull local-db backups to Google Drive#4
Conversation
Co-authored-by: khnumdev <13968776+khnumdev@users.noreply.github.com>
Co-authored-by: khnumdev <13968776+khnumdev@users.noreply.github.com>
cli.py
Outdated
| typer.echo(f"Total entities {'to delete' if dry_run else 'deleted'}: {deleted_sum}") | ||
|
|
||
|
|
||
| @app.command("push") |
There was a problem hiding this comment.
Not sure about this name. Command name should reflect something like to generate the stash and pulling. Maybe db push, being db the command and push/pull the subcommands
There was a problem hiding this comment.
Changed to db command with push and pull as subcommands in commit 6ba91e9.
Usage is now:
lsu db push [VERSION] [-o]lsu db pull [VERSION]
The db command groups all database backup management operations.
Co-authored-by: khnumdev <13968776+khnumdev@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR implements Google Drive backup synchronization for local-db databases, adding db push and db pull subcommands to the CLI for uploading and downloading database backups.
- Added new module
commands/drive_sync.pywith Google Drive integration using pydrive2 - Implemented
db pushanddb pullcommands under a newdbcommand group - Added
local_db_pathconfiguration option toAppConfig
Reviewed Changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| commands/drive_sync.py | New module implementing push/pull operations with Google Drive authentication, folder management, and local-db command execution |
| commands/config.py | Added local_db_path configuration field to support the new drive sync feature |
| commands/init.py | Exported new push_to_drive and pull_from_drive functions for the drive sync feature |
| cli.py | Added db command group with push and pull subcommands for database backup management |
| requirements.txt | Added pydrive2>=1.20.0 dependency for Google Drive API integration |
| pyproject.toml | Added pydrive2>=1.20.0 to project dependencies |
| tests/test_drive_sync_unit.py | Comprehensive unit tests covering path resolution, Drive operations, command execution, and error handling scenarios |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @db_app.command("push") | ||
| def db_push( | ||
| version: Annotated[ | ||
| Optional[str], typer.Argument(help="Version name (defaults to today's date YYYY-mm-DD)") |
There was a problem hiding this comment.
The date format in the help text should be YYYY-MM-DD (capital M for months), not YYYY-mm-DD. The lowercase 'mm' typically represents minutes, while 'MM' represents months. The actual code implementation at line 64 of drive_sync.py correctly uses %Y-%m-%d format.
| Optional[str], typer.Argument(help="Version name (defaults to today's date YYYY-mm-DD)") | |
| Optional[str], typer.Argument(help="Version name (defaults to today's date YYYY-MM-DD)") |
| def _run_local_db_command(local_db_path: str, args: list[str]) -> None: | ||
| cmd = [local_db_path] + args | ||
| logger.info(f"Running: {' '.join(cmd)}") | ||
| result = subprocess.run(cmd, capture_output=True, text=True) |
There was a problem hiding this comment.
[nitpick] Consider adding a timeout parameter to subprocess.run() to prevent the command from hanging indefinitely. For example: subprocess.run(cmd, capture_output=True, text=True, timeout=300) for a 5-minute timeout. This is especially important for network operations that might hang.
| result = subprocess.run(cmd, capture_output=True, text=True) | |
| result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) |
commands/drive_sync.py
Outdated
| logger.info(f"Downloading {backup_file} from Google Drive") | ||
| file_to_download.GetContentFile(backup_file) | ||
|
|
||
| version_to_restore = backup_file.replace("local-db-", "").replace(".bin", "") |
There was a problem hiding this comment.
[nitpick] The version extraction using chained .replace() calls could be fragile if filenames contain the substrings "local-db-" or ".bin" in unexpected places. Consider using a more robust approach with regex, such as:
import re
match = re.match(r'local-db-(.+)\.bin$', backup_file)
if not match:
raise ValueError(f"Invalid backup filename format: {backup_file}")
version_to_restore = match.group(1)This ensures the filename strictly matches the expected format and extracts the version correctly.
Implements Google Drive backup synchronization for local-db with
db pushanddb pullsubcommands.Changes
New module:
commands/drive_sync.pypush_to_drive(): Stash local-db and upload to Drive/datastorefolderpull_from_drive(): Download from Drive and restore local-db/datastorefolderCLI commands
db push [VERSION] [-o]: Defaults to today's date (YYYY-mm-DD),-oto overwritedb pull [VERSION]: Downloads latest backup if VERSION omittedThe commands are grouped under the
dbcommand for better organization of database backup management operations.Configuration
local_db_pathtoAppConfig--local-dbflagDependencies
Usage
Testing
15 unit tests covering path resolution, Drive operations, command execution, and error handling.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.