From 7b7cca9aaec439091f1ee427ea43c7c0aa9591b2 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Mon, 13 Mar 2023 17:46:41 +0530 Subject: [PATCH 1/8] feat: fkdca --- samples/samples/snippets.py | 99 +++++++++++++++ samples/samples/snippets_test.py | 22 ++++ tests/_fixtures.py | 62 +++++++++ tests/system/_helpers.py | 6 + tests/system/test_database_api.py | 202 ++++++++++++++++++++++++++++++ 5 files changed, 391 insertions(+) diff --git a/samples/samples/snippets.py b/samples/samples/snippets.py index a447121010..bae6c12dd9 100644 --- a/samples/samples/snippets.py +++ b/samples/samples/snippets.py @@ -2428,6 +2428,105 @@ def enable_fine_grained_access( # [END spanner_enable_fine_grained_access] +# [START spanner_create_table_with_foreign_key_delete_cascade] +def create_table_with_foreign_key_delete_cascade(instance_id, database_id): + """Creates a table with foreign key delete cascade action""" + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + operation = database.update_ddl( + [ + """CREATE TABLE Customers ( + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + ) PRIMARY KEY (CustomerId) + """, + """ + CREATE TABLE ShoppingCarts ( + CartId INT64 NOT NULL, + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE + ) PRIMARY KEY (CartId) + """ + ] + ) + + print("Waiting for operation to complete...") + operation.result(OPERATION_TIMEOUT_SECONDS) + + print( + """Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId + foreign key constraint on database {} on instance {}""".format( + database_id, instance_id + ) + ) + + +# [END spanner_create_table_with_foreign_key_delete_cascade] + + +# [START spanner_alter_table_with_foreign_key_delete_cascade] +def alter_table_with_foreign_key_delete_cascade(instance_id, database_id): + """Creates a table with foreign key delete cascade action""" + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + operation = database.update_ddl( + [ + """ALTER TABLE ShoppingCarts + ADD CONSTRAINT FKShoppingCartsCustomerName + FOREIGN KEY (CustomerName) + REFERENCES Customers(CustomerName) + ON DELETE CASCADE""" + ] + ) + + print("Waiting for operation to complete...") + operation.result(OPERATION_TIMEOUT_SECONDS) + + print( + """Altered ShoppingCarts table with FKShoppingCartsCustomerName + foreign key constraint on database {} on instance {}""".format( + database_id, instance_id + ) + ) + + +# [END spanner_alter_table_with_foreign_key_delete_cascade] + + +# [START spanner_drop_foreign_key_constraint_delete_cascade] +def drop_foreign_key_contraint_delete_cascade(instance_id, database_id): + """Creates a table with foreign key delete cascade action""" + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + operation = database.update_ddl( + [ + """ALTER TABLE ShoppingCarts + DROP CONSTRAINT FKShoppingCartsCustomerName""" + ] + ) + + print("Waiting for operation to complete...") + operation.result(OPERATION_TIMEOUT_SECONDS) + + print( + """Altered ShoppingCarts table to drop FKShoppingCartsCustomerName + foreign key constraint on database {} on instance {}""".format( + database_id, instance_id + ) + ) + + +# [END spanner_drop_foreign_key_constraint_delete_cascade] + + if __name__ == "__main__": # noqa: C901 parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter diff --git a/samples/samples/snippets_test.py b/samples/samples/snippets_test.py index 6d5822e37b..dd770df8e4 100644 --- a/samples/samples/snippets_test.py +++ b/samples/samples/snippets_test.py @@ -781,3 +781,25 @@ def test_list_database_roles(capsys, instance_id, sample_database): snippets.list_database_roles(instance_id, sample_database.database_id) out, _ = capsys.readouterr() assert "new_parent" in out + + +@pytest.mark.dependency(name="create_table_with_foreign_key_delete_cascade") +def test_create_table_with_foreign_key_delete_cascade(capsys, instance_id, sample_database): + snippets.create_table_with_foreign_key_delete_cascade(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId" in out + + +@pytest.mark.dependency(name="alter_table_with_foreign_key_delete_cascade", + depends=["create_table_with_foreign_key_delete_cascade"]) +def test_alter_table_with_foreign_key_delete_cascade(capsys, instance_id, sample_database): + snippets.alter_table_with_foreign_key_delete_cascade(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Altered ShoppingCarts table with FKShoppingCartsCustomerName" in out + + +@pytest.mark.dependency(depends=["alter_table_with_foreign_key_delete_cascade"]) +def test_drop_foreign_key_contraint_delete_cascade(capsys, instance_id, sample_database): + snippets.drop_foreign_key_contraint_delete_cascade(instance_id, sample_database.database_id) + out, _ = capsys.readouterr() + assert "Altered ShoppingCarts table to drop FKShoppingCartsCustomerName" in out diff --git a/tests/_fixtures.py b/tests/_fixtures.py index 0bd8fe163a..3aa0f53258 100644 --- a/tests/_fixtures.py +++ b/tests/_fixtures.py @@ -68,6 +68,19 @@ email STRING(MAX), deleted BOOL NOT NULL ) PRIMARY KEY(id, commit_ts DESC); + +CREATE TABLE Customers ( + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + ) PRIMARY KEY (CustomerId); + + CREATE TABLE ShoppingCarts ( + CartId INT64 NOT NULL, + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE + ) PRIMARY KEY (CartId); """ EMULATOR_DDL = """\ @@ -157,6 +170,19 @@ name VARCHAR(16), PRIMARY KEY (id)); CREATE INDEX name ON contacts(first_name, last_name); +CREATE TABLE Customers ( + CustomerId BIGINT, + CustomerName VARCHAR(62) NOT NULL, + PRIMARY KEY (CustomerId)); + + CREATE TABLE ShoppingCarts ( + CartId BIGINT, + CustomerId BIGINT NOT NULL, + CustomerName VARCHAR(62) NOT NULL, + CONSTRAINT "FKShoppingCartsCustomerId" FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE, + PRIMARY KEY (CartId) + ); """ DDL_STATEMENTS = [stmt.strip() for stmt in DDL.split(";") if stmt.strip()] @@ -164,3 +190,39 @@ stmt.strip() for stmt in EMULATOR_DDL.split(";") if stmt.strip() ] PG_DDL_STATEMENTS = [stmt.strip() for stmt in PG_DDL.split(";") if stmt.strip()] + +FKDAC_DDL = """\ +CREATE TABLE Customers_ ( + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + ) PRIMARY KEY (CustomerId); + + CREATE TABLE ShoppingCarts_ ( + CartId INT64 NOT NULL, + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) + REFERENCES Customers_ (CustomerId) ON DELETE CASCADE + ) PRIMARY KEY (CartId); +""" + +PG_FKDAC_DDL = """\ +CREATE TABLE Customers_ ( + CustomerId BIGINT, + CustomerName VARCHAR(62) NOT NULL, + PRIMARY KEY (CustomerId)); + + CREATE TABLE ShoppingCarts_ ( + CartId BIGINT, + CustomerId BIGINT NOT NULL, + CustomerName VARCHAR(62) NOT NULL, + CONSTRAINT "FKShoppingCartsCustomerId" FOREIGN KEY (CustomerId) + REFERENCES Customers_ (CustomerId) ON DELETE CASCADE, + PRIMARY KEY (CartId) + ); +""" + +FKDAC_DDL_STATEMENTS = [stmt.strip() for stmt in FKDAC_DDL.split(";") if stmt.strip()] +PG_FKDAC_DDL_STATEMENTS = [ + stmt.strip() for stmt in PG_FKDAC_DDL.split(";") if stmt.strip() +] diff --git a/tests/system/_helpers.py b/tests/system/_helpers.py index 60926b216e..83034c2e20 100644 --- a/tests/system/_helpers.py +++ b/tests/system/_helpers.py @@ -65,6 +65,12 @@ ) ) +FKADC_DDL_STATEMENTS = ( + _fixtures.PG_FKDAC_DDL_STATEMENTS + if DATABASE_DIALECT == "POSTGRESQL" + else _fixtures.FKDAC_DDL_STATEMENTS +) + retry_true = retry.RetryResult(operator.truth) retry_false = retry.RetryResult(operator.not_) diff --git a/tests/system/test_database_api.py b/tests/system/test_database_api.py index 364c159da5..8317df645c 100644 --- a/tests/system/test_database_api.py +++ b/tests/system/test_database_api.py @@ -21,12 +21,17 @@ from google.iam.v1 import policy_pb2 from google.cloud import spanner_v1 from google.cloud.spanner_v1.pool import FixedSizePool, PingingPool +from google.cloud.spanner_admin_database_v1 import DatabaseDialect from google.type import expr_pb2 from . import _helpers from . import _sample_data +from google.api_core.exceptions import FailedPrecondition DBAPI_OPERATION_TIMEOUT = 240 # seconds +FKDCA_CUSTOMERS_COLUMNS = ("CustomerId", "CustomerName") +FKDCA_SHOPPING_CARTS_COLUMNS = ("CartId", "CustomerId", "CustomerName") +ALL_KEYSET = spanner_v1.KeySet(all_=True) @pytest.fixture(scope="module") @@ -562,3 +567,200 @@ def _unit_of_work(transaction, name): rows = list(after.read(sd.COUNTERS_TABLE, sd.COUNTERS_COLUMNS, sd.ALL)) assert len(rows) == 2 + + +def test_create_table_with_foreign_key_delete_cascade_action( + not_emulator, shared_instance, databases_to_delete, database_dialect +): + fkadc_db_id = _helpers.unique_id("fkadc") + + if database_dialect == DatabaseDialect.POSTGRESQL: + fkadc_database = shared_instance.database( + fkadc_db_id, + database_dialect=database_dialect, + ) + operation = fkadc_database.create() + operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. + + operation = fkadc_database.update_ddl( + ddl_statements=_helpers.FKADC_DDL_STATEMENTS + ) + operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. + + else: + fkadc_database = shared_instance.database( + fkadc_db_id, + ddl_statements=_helpers.FKADC_DDL_STATEMENTS, + database_dialect=database_dialect, + ) + operation = fkadc_database.create() + operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. + + databases_to_delete.append(fkadc_database) + + fkadc_database.reload() + assert any( + "FKShoppingCartsCustomerId" in stmt for stmt in fkadc_database.ddl_statements + ) + + +def test_alter_table_with_foreign_key_delete_cascade_action( + not_emulator, shared_database, database_dialect +): + constraint_name = ( + '"FKShoppingCartsCustomerName"' + if database_dialect == DatabaseDialect.POSTGRESQL + else "FKShoppingCartsCustomerName" + ) + ddl_statements_add_constraints = [ + f"ALTER TABLE ShoppingCarts ADD CONSTRAINT {constraint_name}" + f" FOREIGN KEY (CustomerName) REFERENCES Customers(CustomerName) ON DELETE CASCADE" + ] + + operation = shared_database.update_ddl(ddl_statements_add_constraints) + operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. + + shared_database.reload() + assert any( + "FKShoppingCartsCustomerName" in stmt for stmt in shared_database.ddl_statements + ) + ddl_statements_drop_constraints = [ + "ALTER TABLE ShoppingCarts" " DROP CONSTRAINT FKShoppingCartsCustomerName" + ] + + operation = shared_database.update_ddl(ddl_statements_drop_constraints) + operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. + + shared_database.reload() + assert not any( + "FKShoppingCartsCustomerName" in stmt for stmt in shared_database.ddl_statements + ) + + +def test_insertion_in_referencing_table_fkdca(not_emulator, shared_database): + with shared_database.batch() as batch: + batch.insert( + table="Customers", + columns=FKDCA_CUSTOMERS_COLUMNS, + values=[ + (1, "Marc"), + (2, "Catalina"), + ], + ) + + with shared_database.batch() as batch: + batch.insert( + table="ShoppingCarts", + columns=FKDCA_SHOPPING_CARTS_COLUMNS, + values=[ + (1, 1, "Marc"), + ], + ) + + with shared_database.snapshot() as snapshot: + rows = list( + snapshot.read( + "ShoppingCarts", ("CartId", "CustomerId", "CustomerName"), ALL_KEYSET + ) + ) + + assert len(rows) == 1 + + +def test_insertion_in_referencing_table_error_fkdca(not_emulator, shared_database): + with pytest.raises(FailedPrecondition): + with shared_database.batch() as batch: + batch.insert( + table="ShoppingCarts", + columns=FKDCA_SHOPPING_CARTS_COLUMNS, + values=[ + (4, 4, "Naina"), + ], + ) + + +def test_insertion_then_deletion_in_referenced_table_fkdca( + not_emulator, shared_database +): + with shared_database.batch() as batch: + batch.insert( + table="Customers", + columns=FKDCA_CUSTOMERS_COLUMNS, + values=[ + (3, "Sara"), + ], + ) + + with shared_database.batch() as batch: + batch.insert( + table="ShoppingCarts", + columns=FKDCA_SHOPPING_CARTS_COLUMNS, + values=[ + (3, 3, "Sara"), + ], + ) + + with shared_database.snapshot() as snapshot: + rows = list(snapshot.read("ShoppingCarts", ["CartId"], ALL_KEYSET)) + + assert [3] in rows + + with shared_database.batch() as batch: + batch.delete(table="Customers", keyset=spanner_v1.KeySet(keys=[[3]])) + + with shared_database.snapshot() as snapshot: + rows = list(snapshot.read("ShoppingCarts", ["CartId"], ALL_KEYSET)) + + assert [3] not in rows + + +def test_insert_then_delete_referenced_key_error_fkdca(not_emulator, shared_database): + with pytest.raises(exceptions.FailedPrecondition): + with shared_database.batch() as batch: + batch.insert( + table="Customers", + columns=FKDCA_CUSTOMERS_COLUMNS, + values=[ + (3, "Sara"), + ], + ) + batch.delete(table="Customers", keyset=spanner_v1.KeySet(keys=[[3]])) + + +def test_insert_referencing_key_then_delete_referenced_key_error_fkdca( + not_emulator, shared_database +): + with shared_database.batch() as batch: + batch.insert( + table="Customers", + columns=FKDCA_CUSTOMERS_COLUMNS, + values=[ + (4, "Huda"), + ], + ) + + with pytest.raises(exceptions.FailedPrecondition): + with shared_database.batch() as batch: + batch.insert( + table="ShoppingCarts", + columns=FKDCA_SHOPPING_CARTS_COLUMNS, + values=[ + (4, 4, "Huda"), + ], + ) + batch.delete(table="Customers", keyset=spanner_v1.KeySet(keys=[[4]])) + + +def test_information_schema_referential_constraints_fkdca( + not_emulator, shared_database +): + with shared_database.snapshot() as snapshot: + rows = list( + snapshot.execute_sql( + "SELECT DELETE_RULE " + "FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS " + "WHERE CONSTRAINT_NAME = 'FKShoppingCartsCustomerId'" + ) + ) + + assert any("CASCADE" in stmt for stmt in rows) From 069056a0867b000a225b002f2b6414116dcaa04f Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Mon, 13 Mar 2023 17:48:33 +0530 Subject: [PATCH 2/8] lint --- samples/samples/snippets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples/snippets.py b/samples/samples/snippets.py index bae6c12dd9..fe89a19351 100644 --- a/samples/samples/snippets.py +++ b/samples/samples/snippets.py @@ -2500,7 +2500,7 @@ def alter_table_with_foreign_key_delete_cascade(instance_id, database_id): # [START spanner_drop_foreign_key_constraint_delete_cascade] -def drop_foreign_key_contraint_delete_cascade(instance_id, database_id): +def drop_foreign_key_constraint_delete_cascade(instance_id, database_id): """Creates a table with foreign key delete cascade action""" spanner_client = spanner.Client() instance = spanner_client.instance(instance_id) From bab2faa55f89571b8b2e9d9caccb34cd0f318ff9 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Mon, 13 Mar 2023 17:50:17 +0530 Subject: [PATCH 3/8] lint --- tests/system/test_database_api.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/system/test_database_api.py b/tests/system/test_database_api.py index 8317df645c..169a26d854 100644 --- a/tests/system/test_database_api.py +++ b/tests/system/test_database_api.py @@ -25,7 +25,6 @@ from google.type import expr_pb2 from . import _helpers from . import _sample_data -from google.api_core.exceptions import FailedPrecondition DBAPI_OPERATION_TIMEOUT = 240 # seconds @@ -668,7 +667,7 @@ def test_insertion_in_referencing_table_fkdca(not_emulator, shared_database): def test_insertion_in_referencing_table_error_fkdca(not_emulator, shared_database): - with pytest.raises(FailedPrecondition): + with pytest.raises(exceptions.FailedPrecondition): with shared_database.batch() as batch: batch.insert( table="ShoppingCarts", From 51e21e94d61eec853f6bafad2ba77562d1511f6b Mon Sep 17 00:00:00 2001 From: Astha Mohta <35952883+asthamohta@users.noreply.github.com> Date: Thu, 13 Jul 2023 11:11:53 +0530 Subject: [PATCH 4/8] Update samples/samples/snippets.py Co-authored-by: Vishwaraj Anand --- samples/samples/snippets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples/snippets.py b/samples/samples/snippets.py index 69db70e849..5eb23c6252 100644 --- a/samples/samples/snippets.py +++ b/samples/samples/snippets.py @@ -2522,7 +2522,7 @@ def alter_table_with_foreign_key_delete_cascade(instance_id, database_id): # [START spanner_drop_foreign_key_constraint_delete_cascade] def drop_foreign_key_constraint_delete_cascade(instance_id, database_id): - """Creates a table with foreign key delete cascade action""" + """Alter table to drop foreign key delete cascade action""" spanner_client = spanner.Client() instance = spanner_client.instance(instance_id) database = instance.database(database_id) From b4b7e6e1ef0d13448adf119f59b22a89f02f5ad7 Mon Sep 17 00:00:00 2001 From: Astha Mohta <35952883+asthamohta@users.noreply.github.com> Date: Thu, 13 Jul 2023 11:12:01 +0530 Subject: [PATCH 5/8] Update samples/samples/snippets.py Co-authored-by: Vishwaraj Anand --- samples/samples/snippets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples/snippets.py b/samples/samples/snippets.py index 5eb23c6252..cbcb6b9bdc 100644 --- a/samples/samples/snippets.py +++ b/samples/samples/snippets.py @@ -2491,7 +2491,7 @@ def create_table_with_foreign_key_delete_cascade(instance_id, database_id): # [START spanner_alter_table_with_foreign_key_delete_cascade] def alter_table_with_foreign_key_delete_cascade(instance_id, database_id): - """Creates a table with foreign key delete cascade action""" + """Alters a table with foreign key delete cascade action""" spanner_client = spanner.Client() instance = spanner_client.instance(instance_id) database = instance.database(database_id) From 31d63c3a144e034d4ba69b93f83569bcc364bd64 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Wed, 19 Jul 2023 11:59:24 +0530 Subject: [PATCH 6/8] changed --- tests/system/test_database_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/system/test_database_api.py b/tests/system/test_database_api.py index b9b059907b..28529eb7b7 100644 --- a/tests/system/test_database_api.py +++ b/tests/system/test_database_api.py @@ -25,7 +25,6 @@ from google.type import expr_pb2 from . import _helpers from . import _sample_data -from google.cloud.spanner_admin_database_v1 import DatabaseDialect DBAPI_OPERATION_TIMEOUT = 240 # seconds From f1c2e3c8893aef82151803bbfa9bf95598ac91c3 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Thu, 20 Jul 2023 12:52:28 +0530 Subject: [PATCH 7/8] changes --- samples/samples/snippets_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples/snippets_test.py b/samples/samples/snippets_test.py index 1b78fd6d8b..f0824348c0 100644 --- a/samples/samples/snippets_test.py +++ b/samples/samples/snippets_test.py @@ -813,6 +813,6 @@ def test_alter_table_with_foreign_key_delete_cascade(capsys, instance_id, sample @pytest.mark.dependency(depends=["alter_table_with_foreign_key_delete_cascade"]) def test_drop_foreign_key_contraint_delete_cascade(capsys, instance_id, sample_database): - snippets.drop_foreign_key_contraint_delete_cascade(instance_id, sample_database.database_id) + snippets.drop_foreign_key_constraint_delete_cascade(instance_id, sample_database.database_id) out, _ = capsys.readouterr() assert "Altered ShoppingCarts table to drop FKShoppingCartsCustomerName" in out From a7bbcc5f9b2e3f54dc32383e8047a0b8a802d379 Mon Sep 17 00:00:00 2001 From: Astha Mohta Date: Tue, 25 Jul 2023 17:28:31 +0530 Subject: [PATCH 8/8] changes --- tests/_fixtures.py | 36 ----------- tests/system/_helpers.py | 6 -- tests/system/test_database_api.py | 100 +++++------------------------- 3 files changed, 16 insertions(+), 126 deletions(-) diff --git a/tests/_fixtures.py b/tests/_fixtures.py index 3aa0f53258..b6f4108490 100644 --- a/tests/_fixtures.py +++ b/tests/_fixtures.py @@ -190,39 +190,3 @@ stmt.strip() for stmt in EMULATOR_DDL.split(";") if stmt.strip() ] PG_DDL_STATEMENTS = [stmt.strip() for stmt in PG_DDL.split(";") if stmt.strip()] - -FKDAC_DDL = """\ -CREATE TABLE Customers_ ( - CustomerId INT64 NOT NULL, - CustomerName STRING(62) NOT NULL, - ) PRIMARY KEY (CustomerId); - - CREATE TABLE ShoppingCarts_ ( - CartId INT64 NOT NULL, - CustomerId INT64 NOT NULL, - CustomerName STRING(62) NOT NULL, - CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) - REFERENCES Customers_ (CustomerId) ON DELETE CASCADE - ) PRIMARY KEY (CartId); -""" - -PG_FKDAC_DDL = """\ -CREATE TABLE Customers_ ( - CustomerId BIGINT, - CustomerName VARCHAR(62) NOT NULL, - PRIMARY KEY (CustomerId)); - - CREATE TABLE ShoppingCarts_ ( - CartId BIGINT, - CustomerId BIGINT NOT NULL, - CustomerName VARCHAR(62) NOT NULL, - CONSTRAINT "FKShoppingCartsCustomerId" FOREIGN KEY (CustomerId) - REFERENCES Customers_ (CustomerId) ON DELETE CASCADE, - PRIMARY KEY (CartId) - ); -""" - -FKDAC_DDL_STATEMENTS = [stmt.strip() for stmt in FKDAC_DDL.split(";") if stmt.strip()] -PG_FKDAC_DDL_STATEMENTS = [ - stmt.strip() for stmt in PG_FKDAC_DDL.split(";") if stmt.strip() -] diff --git a/tests/system/_helpers.py b/tests/system/_helpers.py index 83034c2e20..60926b216e 100644 --- a/tests/system/_helpers.py +++ b/tests/system/_helpers.py @@ -65,12 +65,6 @@ ) ) -FKADC_DDL_STATEMENTS = ( - _fixtures.PG_FKDAC_DDL_STATEMENTS - if DATABASE_DIALECT == "POSTGRESQL" - else _fixtures.FKDAC_DDL_STATEMENTS -) - retry_true = retry.RetryResult(operator.truth) retry_false = retry.RetryResult(operator.not_) diff --git a/tests/system/test_database_api.py b/tests/system/test_database_api.py index 28529eb7b7..153567810a 100644 --- a/tests/system/test_database_api.py +++ b/tests/system/test_database_api.py @@ -28,8 +28,8 @@ DBAPI_OPERATION_TIMEOUT = 240 # seconds -FKDCA_CUSTOMERS_COLUMNS = ("CustomerId", "CustomerName") -FKDCA_SHOPPING_CARTS_COLUMNS = ("CartId", "CustomerId", "CustomerName") +FKADC_CUSTOMERS_COLUMNS = ("CustomerId", "CustomerName") +FKADC_SHOPPING_CARTS_COLUMNS = ("CartId", "CustomerId", "CustomerName") ALL_KEYSET = spanner_v1.KeySet(all_=True) @@ -575,79 +575,11 @@ def _unit_of_work(transaction, name): assert len(rows) == 2 -def test_create_table_with_foreign_key_delete_cascade_action( - not_emulator, shared_instance, databases_to_delete, database_dialect -): - fkadc_db_id = _helpers.unique_id("fkadc") - - if database_dialect == DatabaseDialect.POSTGRESQL: - fkadc_database = shared_instance.database( - fkadc_db_id, - database_dialect=database_dialect, - ) - operation = fkadc_database.create() - operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. - - operation = fkadc_database.update_ddl( - ddl_statements=_helpers.FKADC_DDL_STATEMENTS - ) - operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. - - else: - fkadc_database = shared_instance.database( - fkadc_db_id, - ddl_statements=_helpers.FKADC_DDL_STATEMENTS, - database_dialect=database_dialect, - ) - operation = fkadc_database.create() - operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. - - databases_to_delete.append(fkadc_database) - - fkadc_database.reload() - assert any( - "FKShoppingCartsCustomerId" in stmt for stmt in fkadc_database.ddl_statements - ) - - -def test_alter_table_with_foreign_key_delete_cascade_action( - not_emulator, shared_database, database_dialect -): - constraint_name = ( - '"FKShoppingCartsCustomerName"' - if database_dialect == DatabaseDialect.POSTGRESQL - else "FKShoppingCartsCustomerName" - ) - ddl_statements_add_constraints = [ - f"ALTER TABLE ShoppingCarts ADD CONSTRAINT {constraint_name}" - f" FOREIGN KEY (CustomerName) REFERENCES Customers(CustomerName) ON DELETE CASCADE" - ] - - operation = shared_database.update_ddl(ddl_statements_add_constraints) - operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. - - shared_database.reload() - assert any( - "FKShoppingCartsCustomerName" in stmt for stmt in shared_database.ddl_statements - ) - ddl_statements_drop_constraints = [ - "ALTER TABLE ShoppingCarts" " DROP CONSTRAINT FKShoppingCartsCustomerName" - ] - - operation = shared_database.update_ddl(ddl_statements_drop_constraints) - operation.result(DBAPI_OPERATION_TIMEOUT) # raises on failure / timeout. - - shared_database.reload() - assert not any( - "FKShoppingCartsCustomerName" in stmt for stmt in shared_database.ddl_statements - ) - - -def test_insertion_in_referencing_table_fkdca(not_emulator, shared_database): +def test_insertion_in_referencing_table_fkadc(not_emulator, shared_database): with shared_database.batch() as batch: batch.insert( table="Customers", - columns=FKDCA_CUSTOMERS_COLUMNS, + columns=FKADC_CUSTOMERS_COLUMNS, values=[ (1, "Marc"), (2, "Catalina"), @@ -657,7 +589,7 @@ def test_insertion_in_referencing_table_fkdca(not_emulator, shared_database): with shared_database.batch() as batch: batch.insert( table="ShoppingCarts", - columns=FKDCA_SHOPPING_CARTS_COLUMNS, + columns=FKADC_SHOPPING_CARTS_COLUMNS, values=[ (1, 1, "Marc"), ], @@ -673,25 +605,25 @@ def test_insertion_in_referencing_table_fkdca(not_emulator, shared_database): assert len(rows) == 1 -def test_insertion_in_referencing_table_error_fkdca(not_emulator, shared_database): +def test_insertion_in_referencing_table_error_fkadc(not_emulator, shared_database): with pytest.raises(exceptions.FailedPrecondition): with shared_database.batch() as batch: batch.insert( table="ShoppingCarts", - columns=FKDCA_SHOPPING_CARTS_COLUMNS, + columns=FKADC_SHOPPING_CARTS_COLUMNS, values=[ (4, 4, "Naina"), ], ) -def test_insertion_then_deletion_in_referenced_table_fkdca( +def test_insertion_then_deletion_in_referenced_table_fkadc( not_emulator, shared_database ): with shared_database.batch() as batch: batch.insert( table="Customers", - columns=FKDCA_CUSTOMERS_COLUMNS, + columns=FKADC_CUSTOMERS_COLUMNS, values=[ (3, "Sara"), ], @@ -700,7 +632,7 @@ def test_insertion_then_deletion_in_referenced_table_fkdca( with shared_database.batch() as batch: batch.insert( table="ShoppingCarts", - columns=FKDCA_SHOPPING_CARTS_COLUMNS, + columns=FKADC_SHOPPING_CARTS_COLUMNS, values=[ (3, 3, "Sara"), ], @@ -720,12 +652,12 @@ def test_insertion_then_deletion_in_referenced_table_fkdca( assert [3] not in rows -def test_insert_then_delete_referenced_key_error_fkdca(not_emulator, shared_database): +def test_insert_then_delete_referenced_key_error_fkadc(not_emulator, shared_database): with pytest.raises(exceptions.FailedPrecondition): with shared_database.batch() as batch: batch.insert( table="Customers", - columns=FKDCA_CUSTOMERS_COLUMNS, + columns=FKADC_CUSTOMERS_COLUMNS, values=[ (3, "Sara"), ], @@ -733,13 +665,13 @@ def test_insert_then_delete_referenced_key_error_fkdca(not_emulator, shared_data batch.delete(table="Customers", keyset=spanner_v1.KeySet(keys=[[3]])) -def test_insert_referencing_key_then_delete_referenced_key_error_fkdca( +def test_insert_referencing_key_then_delete_referenced_key_error_fkadc( not_emulator, shared_database ): with shared_database.batch() as batch: batch.insert( table="Customers", - columns=FKDCA_CUSTOMERS_COLUMNS, + columns=FKADC_CUSTOMERS_COLUMNS, values=[ (4, "Huda"), ], @@ -749,7 +681,7 @@ def test_insert_referencing_key_then_delete_referenced_key_error_fkdca( with shared_database.batch() as batch: batch.insert( table="ShoppingCarts", - columns=FKDCA_SHOPPING_CARTS_COLUMNS, + columns=FKADC_SHOPPING_CARTS_COLUMNS, values=[ (4, 4, "Huda"), ], @@ -757,7 +689,7 @@ def test_insert_referencing_key_then_delete_referenced_key_error_fkdca( batch.delete(table="Customers", keyset=spanner_v1.KeySet(keys=[[4]])) -def test_information_schema_referential_constraints_fkdca( +def test_information_schema_referential_constraints_fkadc( not_emulator, shared_database ): with shared_database.snapshot() as snapshot: