Skip to content

Commit da146b7

Browse files
authored
feat: add samples for PITR (#222)
This PR modifies existing samples and adds a sample to show how to use the PITR feature.
1 parent ec89979 commit da146b7

File tree

2 files changed

+64
-5
lines changed

2 files changed

+64
-5
lines changed

samples/samples/backup_sample.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def create_backup(instance_id, database_id, backup_id):
3434

3535
# Create a backup
3636
expire_time = datetime.utcnow() + timedelta(days=14)
37-
backup = instance.backup(backup_id, database=database, expire_time=expire_time)
37+
version_time = database.earliest_version_time
38+
backup = instance.backup(backup_id, database=database, expire_time=expire_time, version_time=version_time)
3839
operation = backup.create()
3940

4041
# Wait for backup operation to complete.
@@ -47,8 +48,8 @@ def create_backup(instance_id, database_id, backup_id):
4748
# Get the name, create time and backup size.
4849
backup.reload()
4950
print(
50-
"Backup {} of size {} bytes was created at {}".format(
51-
backup.name, backup.size_bytes, backup.create_time
51+
"Backup {} of size {} bytes was created at {} for version of database at {}".format(
52+
backup.name, backup.size_bytes, backup.create_time, backup.version_time
5253
)
5354
)
5455

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

66-
# Start restoring backup to a new database.
67+
# Start restoring an existing backup to a new database.
6768
backup = instance.backup(backup_id)
6869
new_database = instance.database(new_database_id)
6970
operation = new_database.restore(backup)
@@ -75,10 +76,11 @@ def restore_database(instance_id, new_database_id, backup_id):
7576
new_database.reload()
7677
restore_info = new_database.restore_info
7778
print(
78-
"Database {} restored to {} from backup {}.".format(
79+
"Database {} restored to {} from backup {} with version time {}.".format(
7980
restore_info.backup_info.source_database,
8081
new_database_id,
8182
restore_info.backup_info.backup,
83+
restore_info.backup_info.version_time
8284
)
8385
)
8486

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

271273

274+
# [START spanner_create_database_with_version_retention_period]
275+
def create_database_with_version_retention_period(instance_id, database_id, retention_period):
276+
"""Creates a database with a version retention period."""
277+
spanner_client = spanner.Client()
278+
instance = spanner_client.instance(instance_id)
279+
ddl_statements = [
280+
"CREATE TABLE Singers ("
281+
+ " SingerId INT64 NOT NULL,"
282+
+ " FirstName STRING(1024),"
283+
+ " LastName STRING(1024),"
284+
+ " SingerInfo BYTES(MAX)"
285+
+ ") PRIMARY KEY (SingerId)",
286+
"CREATE TABLE Albums ("
287+
+ " SingerId INT64 NOT NULL,"
288+
+ " AlbumId INT64 NOT NULL,"
289+
+ " AlbumTitle STRING(MAX)"
290+
+ ") PRIMARY KEY (SingerId, AlbumId),"
291+
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE",
292+
"ALTER DATABASE `{}`"
293+
" SET OPTIONS (version_retention_period = '{}')".format(
294+
database_id, retention_period
295+
)
296+
]
297+
db = instance.database(database_id, ddl_statements)
298+
operation = db.create()
299+
300+
operation.result(30)
301+
302+
db.reload()
303+
304+
print("Database {} created with version retention period {} and earliest version time {}".format(
305+
db.database_id, db.version_retention_period, db.earliest_version_time
306+
))
307+
308+
db.drop()
309+
310+
# [END spanner_create_database_with_version_retention_period]
311+
312+
272313
if __name__ == "__main__": # noqa: C901
273314
parser = argparse.ArgumentParser(
274315
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter

samples/samples/backup_sample_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ def unique_backup_id():
3838

3939
INSTANCE_ID = unique_instance_id()
4040
DATABASE_ID = unique_database_id()
41+
RETENTION_DATABASE_ID = unique_database_id()
4142
RESTORE_DB_ID = unique_database_id()
4243
BACKUP_ID = unique_backup_id()
44+
RETENTION_PERIOD = "7d"
4345

4446

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

7274

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

8184

85+
# Depends on test_create_backup having run first
8286
def test_list_backup_operations(capsys, spanner_instance):
8387
backup_sample.list_backup_operations(INSTANCE_ID, DATABASE_ID)
8488
out, _ = capsys.readouterr()
8589
assert BACKUP_ID in out
8690
assert DATABASE_ID in out
8791

8892

93+
# Depends on test_create_backup having run first
8994
def test_list_backups(capsys, spanner_instance):
9095
backup_sample.list_backups(INSTANCE_ID, DATABASE_ID, BACKUP_ID)
9196
out, _ = capsys.readouterr()
9297
id_count = out.count(BACKUP_ID)
9398
assert id_count == 7
9499

95100

101+
# Depends on test_create_backup having run first
96102
def test_update_backup(capsys):
97103
backup_sample.update_backup(INSTANCE_ID, BACKUP_ID)
98104
out, _ = capsys.readouterr()
99105
assert BACKUP_ID in out
100106

101107

108+
# Depends on test_create_backup having run first
102109
def test_delete_backup(capsys, spanner_instance):
103110
backup_sample.delete_backup(INSTANCE_ID, BACKUP_ID)
104111
out, _ = capsys.readouterr()
105112
assert BACKUP_ID in out
106113

107114

115+
# Depends on test_create_backup having run first
108116
def test_cancel_backup(capsys):
109117
backup_sample.cancel_backup(INSTANCE_ID, DATABASE_ID, BACKUP_ID)
110118
out, _ = capsys.readouterr()
@@ -113,3 +121,13 @@ def test_cancel_backup(capsys):
113121
"Backup deleted." in out
114122
)
115123
assert cancel_success or cancel_failure
124+
125+
126+
@RetryErrors(exception=DeadlineExceeded, max_tries=2)
127+
def test_create_database_with_retention_period(capsys, spanner_instance):
128+
backup_sample.create_database_with_version_retention_period(INSTANCE_ID, RETENTION_DATABASE_ID, RETENTION_PERIOD)
129+
out, _ = capsys.readouterr()
130+
assert (RETENTION_DATABASE_ID + " created with ") in out
131+
assert ("retention period " + RETENTION_PERIOD) in out
132+
database = spanner_instance.database(RETENTION_DATABASE_ID)
133+
database.drop()

0 commit comments

Comments
 (0)