Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add samples for PITR #222

Merged
merged 12 commits into from Feb 25, 2021
53 changes: 47 additions & 6 deletions samples/samples/backup_sample.py
Expand Up @@ -34,7 +34,8 @@ def create_backup(instance_id, database_id, backup_id):

# Create a backup
expire_time = datetime.utcnow() + timedelta(days=14)
backup = instance.backup(backup_id, database=database, expire_time=expire_time)
version_time = database.earliest_version_time
backup = instance.backup(backup_id, database=database, expire_time=expire_time, version_time=version_time)
operation = backup.create()

# Wait for backup operation to complete.
Expand All @@ -47,8 +48,8 @@ def create_backup(instance_id, database_id, backup_id):
# Get the name, create time and backup size.
backup.reload()
print(
"Backup {} of size {} bytes was created at {}".format(
backup.name, backup.size_bytes, backup.create_time
"Backup {} of size {} bytes was created at {} for version of database at {}".format(
backup.name, backup.size_bytes, backup.create_time, backup.version_time
)
)

Expand All @@ -63,7 +64,7 @@ def restore_database(instance_id, new_database_id, backup_id):
instance = spanner_client.instance(instance_id)
# Create a backup on database_id.

# Start restoring backup to a new database.
# Start restoring an existing backup to a new database.
backup = instance.backup(backup_id)
new_database = instance.database(new_database_id)
operation = new_database.restore(backup)
Expand All @@ -75,10 +76,11 @@ def restore_database(instance_id, new_database_id, backup_id):
new_database.reload()
restore_info = new_database.restore_info
print(
"Database {} restored to {} from backup {}.".format(
"Database {} restored to {} from backup {} with version time {}.".format(
restore_info.backup_info.source_database,
new_database_id,
restore_info.backup_info.backup,
restore_info.backup_info.version_time
)
)

Expand Down Expand Up @@ -269,6 +271,45 @@ def update_backup(instance_id, backup_id):
# [END spanner_update_backup]


# [START spanner_create_database_with_version_retention_period]
def create_database_with_version_retention_period(instance_id, database_id, retention_period):
"""Creates a database with a version retention period."""
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
ddl_statements = [
"CREATE TABLE Singers ("
+ " SingerId INT64 NOT NULL,"
+ " FirstName STRING(1024),"
+ " LastName STRING(1024),"
+ " SingerInfo BYTES(MAX)"
+ ") PRIMARY KEY (SingerId)",
"CREATE TABLE Albums ("
+ " SingerId INT64 NOT NULL,"
+ " AlbumId INT64 NOT NULL,"
+ " AlbumTitle STRING(MAX)"
+ ") PRIMARY KEY (SingerId, AlbumId),"
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE",
"ALTER DATABASE `{}`"
" SET OPTIONS (version_retention_period = '{}')".format(
database_id, retention_period
)
]
db = instance.database(database_id, ddl_statements)
operation = db.create()

operation.result(30)

db.reload()

print("Database {} created with version retention period {} and earliest version time {}".format(
db.database_id, db.version_retention_period, db.earliest_version_time
))

db.drop()

# [END spanner_create_database_with_version_retention_period]


if __name__ == "__main__": # noqa: C901
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
Expand Down Expand Up @@ -302,7 +343,7 @@ def update_backup(instance_id, backup_id):
elif args.command == "update_backup":
update_backup(args.instance_id, args.backup_id)
elif args.command == "restore_database":
restore_database(args.instance_id, args.database_id, args.backup_id)
restore_database(args.instance_id, args.backup_id)
zoercai marked this conversation as resolved.
Show resolved Hide resolved
elif args.command == "list_backups":
list_backups(args.instance_id, args.database_id, args.backup_id)
elif args.command == "list_backup_operations":
Expand Down
18 changes: 18 additions & 0 deletions samples/samples/backup_sample_test.py
Expand Up @@ -38,8 +38,10 @@ def unique_backup_id():

INSTANCE_ID = unique_instance_id()
DATABASE_ID = unique_database_id()
DATABASE_ID_2 = unique_database_id()
zoercai marked this conversation as resolved.
Show resolved Hide resolved
RESTORE_DB_ID = unique_database_id()
BACKUP_ID = unique_backup_id()
RETENTION_PERIOD = "7d"


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -70,6 +72,7 @@ def test_create_backup(capsys, database):
assert BACKUP_ID in out


# Depends on test_create_backup having run first
@RetryErrors(exception=DeadlineExceeded, max_tries=2)
def test_restore_database(capsys):
backup_sample.restore_database(INSTANCE_ID, RESTORE_DB_ID, BACKUP_ID)
Expand All @@ -79,32 +82,37 @@ def test_restore_database(capsys):
assert BACKUP_ID in out


# Depends on test_create_backup having run first
def test_list_backup_operations(capsys, spanner_instance):
backup_sample.list_backup_operations(INSTANCE_ID, DATABASE_ID)
out, _ = capsys.readouterr()
assert BACKUP_ID in out
assert DATABASE_ID in out


# Depends on test_create_backup having run first
def test_list_backups(capsys, spanner_instance):
backup_sample.list_backups(INSTANCE_ID, DATABASE_ID, BACKUP_ID)
out, _ = capsys.readouterr()
id_count = out.count(BACKUP_ID)
assert id_count == 7


# Depends on test_create_backup having run first
def test_update_backup(capsys):
backup_sample.update_backup(INSTANCE_ID, BACKUP_ID)
out, _ = capsys.readouterr()
assert BACKUP_ID in out


# Depends on test_create_backup having run first
def test_delete_backup(capsys, spanner_instance):
backup_sample.delete_backup(INSTANCE_ID, BACKUP_ID)
out, _ = capsys.readouterr()
assert BACKUP_ID in out


# Depends on test_create_backup having run first
def test_cancel_backup(capsys):
backup_sample.cancel_backup(INSTANCE_ID, DATABASE_ID, BACKUP_ID)
out, _ = capsys.readouterr()
Expand All @@ -113,3 +121,13 @@ def test_cancel_backup(capsys):
"Backup deleted." in out
)
assert cancel_success or cancel_failure


@RetryErrors(exception=DeadlineExceeded, max_tries=2)
def test_create_database_with_retention_period(capsys, spanner_instance):
backup_sample.create_database_with_version_retention_period(INSTANCE_ID, DATABASE_ID_2, RETENTION_PERIOD)
out, _ = capsys.readouterr()
assert (DATABASE_ID_2 + " created with ") in out
assert ("retention period " + RETENTION_PERIOD) in out
database = spanner_instance.database(DATABASE_ID_2)
database.drop()