Skip to content

Commit 81530ac

Browse files
committed
incorporate suggestions
1 parent 2d8a528 commit 81530ac

File tree

4 files changed

+451
-8
lines changed

4 files changed

+451
-8
lines changed

samples/samples/admin/pg_samples.py

Lines changed: 246 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,73 @@
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+
)
40+
41+
operation = spanner_client.database_admin_api.create_database(request=request)
42+
43+
print("Waiting for operation to complete...")
44+
database = operation.result(OPERATION_TIMEOUT_SECONDS)
45+
46+
create_table_using_ddl(database.name)
47+
print("Created database {} on instance {}".format(database_id, instance_id))
48+
49+
50+
def create_table_using_ddl(database_name):
51+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
52+
53+
spanner_client = spanner.Client()
54+
request = spanner_database_admin.UpdateDatabaseDdlRequest(
55+
database=database_name,
56+
statements=[
57+
"""CREATE TABLE Singers (
58+
SingerId bigint NOT NULL,
59+
FirstName character varying(1024),
60+
LastName character varying(1024),
61+
SingerInfo bytea,
62+
FullName character varying(2048)
63+
GENERATED ALWAYS AS (FirstName || ' ' || LastName) STORED,
64+
PRIMARY KEY (SingerId)
65+
)""",
66+
"""CREATE TABLE Albums (
67+
SingerId bigint NOT NULL,
68+
AlbumId bigint NOT NULL,
69+
AlbumTitle character varying(1024),
70+
PRIMARY KEY (SingerId, AlbumId)
71+
) INTERLEAVE IN PARENT Singers ON DELETE CASCADE""",
72+
],
73+
)
74+
operation = spanner_client.database_admin_api.update_database_ddl(request)
75+
operation.result(OPERATION_TIMEOUT_SECONDS)
76+
77+
78+
# [END spanner_postgresql_create_database]
79+
80+
2781
def create_table_with_datatypes(instance_id, database_id):
2882
"""Creates a table with supported datatypes."""
2983
# [START spanner_postgresql_create_table_with_datatypes]
3084
# instance_id = "your-spanner-instance"
3185
# database_id = "your-spanner-db-id"
86+
87+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
88+
3289
spanner_client = spanner.Client()
3390
instance = spanner_client.instance(instance_id)
3491
database = instance.database(database_id)
@@ -61,6 +118,31 @@ def create_table_with_datatypes(instance_id, database_id):
61118
# [END spanner_postgresql_create_table_with_datatypes]
62119

63120

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

166+
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
167+
84168
spanner_client = spanner.Client()
85169
instance = spanner_client.instance(instance_id)
86170
database = instance.database(database_id)
@@ -103,3 +187,164 @@ def add_jsonb_column(instance_id, database_id):
103187

104188

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