Skip to content

Commit f18d0e1

Browse files
committed
incorporate suggestions
1 parent 2d8a528 commit f18d0e1

File tree

4 files changed

+452
-8
lines changed

4 files changed

+452
-8
lines changed

samples/samples/admin/pg_samples.py

Lines changed: 247 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,74 @@
1919
For more information, see the README.rst under /spanner.
2020
"""
2121
from google.cloud import spanner
22-
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
22+
from google.cloud.spanner_admin_database_v1.types.common import DatabaseDialect
2323

2424
OPERATION_TIMEOUT_SECONDS = 240
2525

2626

27+
# [START spanner_postgresql_create_database]
28+
def create_database(instance_id, database_id):
29+
"""Creates a PostgreSql database and tables for sample data."""
30+
31+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
32+
33+
spanner_client = spanner.Client()
34+
instance = spanner_client.instance(instance_id)
35+
36+
request = spanner_database_admin.CreateDatabaseRequest(
37+
parent=instance.name,
38+
create_statement=f'CREATE DATABASE "{database_id}"',
39+
database_dialect=DatabaseDialect.POSTGRESQL,
40+
)
41+
42+
operation = spanner_client.database_admin_api.create_database(request=request)
43+
44+
print("Waiting for operation to complete...")
45+
database = operation.result(OPERATION_TIMEOUT_SECONDS)
46+
47+
create_table_using_ddl(database.name)
48+
print("Created database {} on instance {}".format(database_id, instance_id))
49+
50+
51+
def create_table_using_ddl(database_name):
52+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
53+
54+
spanner_client = spanner.Client()
55+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
56+
database=database_name,
57+
statements=[
58+
"""CREATE TABLE Singers (
59+
SingerId bigint NOT NULL,
60+
FirstName character varying(1024),
61+
LastName character varying(1024),
62+
SingerInfo bytea,
63+
FullName character varying(2048)
64+
GENERATED ALWAYS AS (FirstName || ' ' || LastName) STORED,
65+
PRIMARY KEY (SingerId)
66+
)""",
67+
"""CREATE TABLE Albums (
68+
SingerId bigint NOT NULL,
69+
AlbumId bigint NOT NULL,
70+
AlbumTitle character varying(1024),
71+
PRIMARY KEY (SingerId, AlbumId)
72+
) INTERLEAVE IN PARENT Singers ON DELETE CASCADE""",
73+
],
74+
)
75+
operation = spanner_client.database_admin_api.update_database_ddl(request)
76+
operation.result(OPERATION_TIMEOUT_SECONDS)
77+
78+
79+
# [END spanner_postgresql_create_database]
80+
81+
2782
def create_table_with_datatypes(instance_id, database_id):
2883
"""Creates a table with supported datatypes."""
2984
# [START spanner_postgresql_create_table_with_datatypes]
3085
# instance_id = "your-spanner-instance"
3186
# database_id = "your-spanner-db-id"
87+
88+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
89+
3290
spanner_client = spanner.Client()
3391
instance = spanner_client.instance(instance_id)
3492
database = instance.database(database_id)
@@ -61,6 +119,31 @@ def create_table_with_datatypes(instance_id, database_id):
61119
# [END spanner_postgresql_create_table_with_datatypes]
62120

63121

122+
# [START spanner_postgresql_add_column]
123+
def add_column(instance_id, database_id):
124+
"""Adds a new column to the Albums table in the example database."""
125+
126+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
127+
128+
spanner_client = spanner.Client()
129+
instance = spanner_client.instance(instance_id)
130+
database = instance.database(database_id)
131+
132+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
133+
database=database.name,
134+
statements=["ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT"],
135+
)
136+
operation = spanner_client.database_admin_api.update_database_ddl(request)
137+
138+
print("Waiting for operation to complete...")
139+
operation.result(OPERATION_TIMEOUT_SECONDS)
140+
141+
print("Added the MarketingBudget column.")
142+
143+
144+
# [END spanner_postgresql_add_column]
145+
146+
64147
# [START spanner_postgresql_jsonb_add_column]
65148
def add_jsonb_column(instance_id, database_id):
66149
"""
@@ -81,6 +164,8 @@ def add_jsonb_column(instance_id, database_id):
81164
# instance_id = "your-spanner-instance"
82165
# database_id = "your-spanner-db-id"
83166

167+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
168+
84169
spanner_client = spanner.Client()
85170
instance = spanner_client.instance(instance_id)
86171
database = instance.database(database_id)
@@ -103,3 +188,164 @@ def add_jsonb_column(instance_id, database_id):
103188

104189

105190
# [END spanner_postgresql_jsonb_add_column]
191+
192+
193+
# [START spanner_postgresql_create_storing_index]
194+
def add_storing_index(instance_id, database_id):
195+
"""Adds an storing index to the example database."""
196+
197+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
198+
199+
spanner_client = spanner.Client()
200+
instance = spanner_client.instance(instance_id)
201+
database = instance.database(database_id)
202+
203+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
204+
database=database.name,
205+
statements=[
206+
"CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle)"
207+
"INCLUDE (MarketingBudget)"
208+
],
209+
)
210+
211+
operation = spanner_client.database_admin_api.update_database_ddl(request)
212+
213+
print("Waiting for operation to complete...")
214+
operation.result(OPERATION_TIMEOUT_SECONDS)
215+
216+
print("Added the AlbumsByAlbumTitle2 index.")
217+
218+
219+
# [END spanner_postgresql_create_storing_index]
220+
221+
222+
# [START spanner_postgresql_create_sequence]
223+
def create_sequence(instance_id, database_id):
224+
"""Creates the Sequence and insert data"""
225+
226+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
227+
228+
spanner_client = spanner.Client()
229+
instance = spanner_client.instance(instance_id)
230+
database = instance.database(database_id)
231+
232+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
233+
database=database.name,
234+
statements=[
235+
"CREATE SEQUENCE Seq BIT_REVERSED_POSITIVE",
236+
"""CREATE TABLE Customers (
237+
CustomerId BIGINT DEFAULT nextval('Seq'),
238+
CustomerName character varying(1024),
239+
PRIMARY KEY (CustomerId)
240+
)""",
241+
],
242+
)
243+
operation = spanner_client.database_admin_api.update_database_ddl(request)
244+
print("Waiting for operation to complete...")
245+
operation.result(OPERATION_TIMEOUT_SECONDS)
246+
247+
print(
248+
"Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value on database {} on instance {}".format(
249+
database_id, instance_id
250+
)
251+
)
252+
253+
def insert_customers(transaction):
254+
results = transaction.execute_sql(
255+
"INSERT INTO Customers (CustomerName) VALUES "
256+
"('Alice'), "
257+
"('David'), "
258+
"('Marc') "
259+
"RETURNING CustomerId"
260+
)
261+
for result in results:
262+
print("Inserted customer record with Customer Id: {}".format(*result))
263+
print(
264+
"Number of customer records inserted is {}".format(
265+
results.stats.row_count_exact
266+
)
267+
)
268+
269+
database.run_in_transaction(insert_customers)
270+
271+
272+
# [END spanner_postgresql_create_sequence]
273+
274+
275+
# [START spanner_postgresql_alter_sequence]
276+
def alter_sequence(instance_id, database_id):
277+
"""Alters the Sequence and insert data"""
278+
279+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
280+
281+
spanner_client = spanner.Client()
282+
instance = spanner_client.instance(instance_id)
283+
database = instance.database(database_id)
284+
285+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
286+
database=database.name,
287+
statements=["ALTER SEQUENCE Seq SKIP RANGE 1000 5000000"],
288+
)
289+
operation = spanner_client.database_admin_api.update_database_ddl(request)
290+
291+
print("Waiting for operation to complete...")
292+
operation.result(OPERATION_TIMEOUT_SECONDS)
293+
294+
print(
295+
"Altered Seq sequence to skip an inclusive range between 1000 and 5000000 on database {} on instance {}".format(
296+
database_id, instance_id
297+
)
298+
)
299+
300+
def insert_customers(transaction):
301+
results = transaction.execute_sql(
302+
"INSERT INTO Customers (CustomerName) VALUES "
303+
"('Lea'), "
304+
"('Cataline'), "
305+
"('Smith') "
306+
"RETURNING CustomerId"
307+
)
308+
for result in results:
309+
print("Inserted customer record with Customer Id: {}".format(*result))
310+
print(
311+
"Number of customer records inserted is {}".format(
312+
results.stats.row_count_exact
313+
)
314+
)
315+
316+
database.run_in_transaction(insert_customers)
317+
318+
319+
# [END spanner_postgresql_alter_sequence]
320+
321+
322+
# [START spanner_postgresql_drop_sequence]
323+
def drop_sequence(instance_id, database_id):
324+
"""Drops the Sequence"""
325+
326+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
327+
328+
spanner_client = spanner.Client()
329+
instance = spanner_client.instance(instance_id)
330+
database = instance.database(database_id)
331+
332+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
333+
database=database.name,
334+
statements=[
335+
"ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT",
336+
"DROP SEQUENCE Seq",
337+
],
338+
)
339+
operation = spanner_client.database_admin_api.update_database_ddl(request)
340+
341+
print("Waiting for operation to complete...")
342+
operation.result(OPERATION_TIMEOUT_SECONDS)
343+
344+
print(
345+
"Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence on database {} on instance {}".format(
346+
database_id, instance_id
347+
)
348+
)
349+
350+
351+
# [END spanner_postgresql_drop_sequence]

samples/samples/admin/pg_samples_test.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,75 @@ def default_leader():
104104
return "us-east4"
105105

106106

107+
@pytest.mark.dependency(name="create_database")
108+
def test_create_database_explicit(sample_instance, create_database_id):
109+
# Rather than re-use 'sample_database', we create a new database, to
110+
# ensure that the 'create_database' snippet is tested.
111+
samples.create_database(sample_instance.instance_id, create_database_id)
112+
database = sample_instance.database(create_database_id)
113+
database.drop()
114+
115+
107116
@pytest.mark.dependency(name="create_table_with_datatypes")
108117
def test_create_table_with_datatypes(capsys, instance_id, sample_database):
109118
samples.create_table_with_datatypes(instance_id, sample_database.database_id)
110119
out, _ = capsys.readouterr()
111120
assert "Created Venues table on database" in out
112121

113122

114-
@pytest.mark.dependency(name="add_jsonb_column", depends=["insert_datatypes_data"])
123+
@pytest.mark.dependency(name="add_column", depends=["create_database"])
124+
def test_add_column(capsys, instance_id, sample_database):
125+
samples.add_column(instance_id, sample_database.database_id)
126+
out, _ = capsys.readouterr()
127+
assert "Added the MarketingBudget column." in out
128+
129+
130+
@pytest.mark.dependency(name="add_storing_index", depends=["create_database"])
131+
def test_add_storing_index(capsys, instance_id, sample_database):
132+
samples.add_storing_index(instance_id, sample_database.database_id)
133+
out, _ = capsys.readouterr()
134+
assert "Added the AlbumsByAlbumTitle2 index." in out
135+
136+
137+
@pytest.mark.dependency(
138+
name="add_jsonb_column", depends=["create_table_with_datatypes"]
139+
)
115140
def test_add_jsonb_column(capsys, instance_id, sample_database):
116141
samples.add_jsonb_column(instance_id, sample_database.database_id)
117142
out, _ = capsys.readouterr()
118143
assert "Waiting for operation to complete..." in out
119144
assert 'Altered table "Venues" on database ' in out
145+
146+
147+
@pytest.mark.dependency(name="create_sequence")
148+
def test_create_sequence(capsys, instance_id, bit_reverse_sequence_database):
149+
samples.create_sequence(instance_id, bit_reverse_sequence_database.database_id)
150+
out, _ = capsys.readouterr()
151+
assert (
152+
"Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value on database"
153+
in out
154+
)
155+
assert "Number of customer records inserted is 3" in out
156+
assert "Inserted customer record with Customer Id:" in out
157+
158+
159+
@pytest.mark.dependency(name="alter_sequence", depends=["create_sequence"])
160+
def test_alter_sequence(capsys, instance_id, bit_reverse_sequence_database):
161+
samples.alter_sequence(instance_id, bit_reverse_sequence_database.database_id)
162+
out, _ = capsys.readouterr()
163+
assert (
164+
"Altered Seq sequence to skip an inclusive range between 1000 and 5000000 on database"
165+
in out
166+
)
167+
assert "Number of customer records inserted is 3" in out
168+
assert "Inserted customer record with Customer Id:" in out
169+
170+
171+
@pytest.mark.dependency(depends=["alter_sequence"])
172+
def test_drop_sequence(capsys, instance_id, bit_reverse_sequence_database):
173+
samples.drop_sequence(instance_id, bit_reverse_sequence_database.database_id)
174+
out, _ = capsys.readouterr()
175+
assert (
176+
"Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence on database"
177+
in out
178+
)

0 commit comments

Comments
 (0)