Skip to content
Permalink
Browse files
feat: add samples for PITR (#222)
This PR modifies existing samples and adds a sample to show how to use the PITR feature.
  • Loading branch information
zoercai committed Feb 25, 2021
1 parent ec89979 commit da146b7a5d1d2ab6795c53301656d39e5594962f
Showing with 64 additions and 5 deletions.
  1. +46 −5 samples/samples/backup_sample.py
  2. +18 −0 samples/samples/backup_sample_test.py
@@ -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.
@@ -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
)
)

@@ -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)
@@ -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
)
)

@@ -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
@@ -38,8 +38,10 @@ def unique_backup_id():

INSTANCE_ID = unique_instance_id()
DATABASE_ID = unique_database_id()
RETENTION_DATABASE_ID = unique_database_id()
RESTORE_DB_ID = unique_database_id()
BACKUP_ID = unique_backup_id()
RETENTION_PERIOD = "7d"


@pytest.fixture(scope="module")
@@ -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)
@@ -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()
@@ -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, RETENTION_DATABASE_ID, RETENTION_PERIOD)
out, _ = capsys.readouterr()
assert (RETENTION_DATABASE_ID + " created with ") in out
assert ("retention period " + RETENTION_PERIOD) in out
database = spanner_instance.database(RETENTION_DATABASE_ID)
database.drop()

0 comments on commit da146b7

Please sign in to comment.