From 27cb48f353b723bee4045e93c8e24f420a8030c3 Mon Sep 17 00:00:00 2001 From: katarinasupe Date: Mon, 24 Jun 2024 13:39:04 +0200 Subject: [PATCH 1/5] Add transactions queries --- gqlalchemy/vendors/memgraph.py | 58 ++++++++++++++++++++++++++++++++++ tests/ogm/test_transactions.py | 8 +++++ 2 files changed, 66 insertions(+) create mode 100644 tests/ogm/test_transactions.py diff --git a/gqlalchemy/vendors/memgraph.py b/gqlalchemy/vendors/memgraph.py index 6918b19a..a20d76d7 100644 --- a/gqlalchemy/vendors/memgraph.py +++ b/gqlalchemy/vendors/memgraph.py @@ -40,6 +40,24 @@ __all__ = ("Memgraph",) +class MemgraphTransaction: + def __init__(self, username: str, transaction_id: str, query: list, metadata: dict): + self.username = (username,) + self.transaction_id = transaction_id + self.query = query + self.metadata = metadata + + def __repr__(self): + return f"MemgraphTransaction(username={self.username}, transaction_id={self.transaction_id}, query={self.query}, metadata={self.metadata})" + + +class MemgraphTerminatedTransaction: + def __init__(self, transaction_id: str, killed: bool): + self.transaction_id = transaction_id + self.killed = killed + def __repr__(self): + return f"MemgraphTerminatedTransaction(transaction_id={self.transaction_id}, killed={self.killed})" + class MemgraphConstants: CONSTRAINT_TYPE = "constraint type" EXISTS = "exists" @@ -432,3 +450,43 @@ def with_power_bi(self) -> "Memgraph": module_name = "power_bi_stream.py" return self.add_query_module(file_path=file_path, module_name=module_name) + + def get_transactions(self) -> List[MemgraphTransaction]: + """Get all transactions in the database. + Returns: + List[MemgraphTransaction]: A list of MemgraphTransaction objects. + """ + + transactions_data = self.execute_and_fetch("SHOW TRANSACTIONS;") + transactions = [] + + for transaction_data in transactions_data: + transaction = MemgraphTransaction( + username=transaction_data["username"], + transaction_id=transaction_data["transaction_id"], + query=transaction_data["query"], + metadata=transaction_data["metadata"], + ) + transactions.append(transaction) + + return transactions + + def terminate_transactions(self, transaction_ids: List[str]) -> List[MemgraphTerminatedTransaction]: + """Terminate transactions in the database. + Args: + transaction_ids (List[str]): A list of transaction ids to terminate. + Returns: + List[MemgraphTerminatedTransaction]: A list of MemgraphTerminatedTransaction objects with info on their status. + """ + + query = ( + "TERMINATE TRANSACTIONS " + ", ".join([f"'{transaction_id}'" for transaction_id in transaction_ids]) + ";" + ) + print(query) + terminated_transactions = [] + results = self.execute_and_fetch(query) + + for result in results: + terminated_transactions.append(MemgraphTerminatedTransaction(result["transaction_id"], result["killed"])) + print(terminated_transactions) + return terminated_transactions diff --git a/tests/ogm/test_transactions.py b/tests/ogm/test_transactions.py new file mode 100644 index 00000000..3cd71dde --- /dev/null +++ b/tests/ogm/test_transactions.py @@ -0,0 +1,8 @@ +def test_get_transactions(memgraph): + result = memgraph.get_transactions() + assert len(result) == 1 + assert result[0].username == ("",) + assert result[0].transaction_id != "" + assert result[0].query == ["SHOW TRANSACTIONS;"] + assert result[0].metadata == {} + From 73cd237af8fe0958df265aeb765ee068c1832bc1 Mon Sep 17 00:00:00 2001 From: katarinasupe Date: Mon, 24 Jun 2024 13:43:16 +0200 Subject: [PATCH 2/5] update mg version --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b221fdc1..a20cdab7 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,7 +1,7 @@ name: Build and Test env: - MG_VERSION: "2.5.0" + MG_VERSION: "2.17.0" POETRY_VERSION: "1.2.2" on: From 5cda32a53e1bff36348698cff07daeeadf79ba7b Mon Sep 17 00:00:00 2001 From: katarinasupe Date: Mon, 24 Jun 2024 16:29:51 +0200 Subject: [PATCH 3/5] flake8 + black --- gqlalchemy/vendors/memgraph.py | 2 ++ tests/ogm/test_transactions.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gqlalchemy/vendors/memgraph.py b/gqlalchemy/vendors/memgraph.py index a20d76d7..d1ac7fde 100644 --- a/gqlalchemy/vendors/memgraph.py +++ b/gqlalchemy/vendors/memgraph.py @@ -55,9 +55,11 @@ class MemgraphTerminatedTransaction: def __init__(self, transaction_id: str, killed: bool): self.transaction_id = transaction_id self.killed = killed + def __repr__(self): return f"MemgraphTerminatedTransaction(transaction_id={self.transaction_id}, killed={self.killed})" + class MemgraphConstants: CONSTRAINT_TYPE = "constraint type" EXISTS = "exists" diff --git a/tests/ogm/test_transactions.py b/tests/ogm/test_transactions.py index 3cd71dde..f304a8bb 100644 --- a/tests/ogm/test_transactions.py +++ b/tests/ogm/test_transactions.py @@ -5,4 +5,3 @@ def test_get_transactions(memgraph): assert result[0].transaction_id != "" assert result[0].query == ["SHOW TRANSACTIONS;"] assert result[0].metadata == {} - From dcc22d69bbe030887d9fe9562966ba7d5c0cdd65 Mon Sep 17 00:00:00 2001 From: katarinasupe Date: Tue, 25 Jun 2024 13:48:44 +0200 Subject: [PATCH 4/5] Add test + review comments --- gqlalchemy/vendors/memgraph.py | 48 +++++++++++++++++++++++----------- tests/ogm/test_transactions.py | 7 +++++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/gqlalchemy/vendors/memgraph.py b/gqlalchemy/vendors/memgraph.py index d1ac7fde..13ec5eb2 100644 --- a/gqlalchemy/vendors/memgraph.py +++ b/gqlalchemy/vendors/memgraph.py @@ -69,6 +69,34 @@ class MemgraphConstants: UNIQUE = "unique" +def create_transaction(transaction_data) -> MemgraphTransaction: + """Create a MemgraphTransaction object from transaction data. + Args: + transaction_data (dict): A dictionary containing transaction data. + Returns: + MemgraphTransaction: A MemgraphTransaction object. + """ + return MemgraphTransaction( + username=transaction_data["username"], + transaction_id=transaction_data["transaction_id"], + query=transaction_data["query"], + metadata=transaction_data["metadata"], + ) + + +def create_terminated_transaction(transaction_data) -> MemgraphTerminatedTransaction: + """Create a MemgraphTerminatedTransaction object from transaction data. + Args: + transaction_data (dict): A dictionary containing transaction data. + Returns: + MemgraphTerminatedTransaction: A MemgraphTerminatedTransaction object. + """ + return MemgraphTerminatedTransaction( + transaction_id=transaction_data["transaction_id"], + killed=transaction_data["killed"], + ) + + class Memgraph(DatabaseClient): def __init__( self, @@ -460,16 +488,7 @@ def get_transactions(self) -> List[MemgraphTransaction]: """ transactions_data = self.execute_and_fetch("SHOW TRANSACTIONS;") - transactions = [] - - for transaction_data in transactions_data: - transaction = MemgraphTransaction( - username=transaction_data["username"], - transaction_id=transaction_data["transaction_id"], - query=transaction_data["query"], - metadata=transaction_data["metadata"], - ) - transactions.append(transaction) + transactions = list(map(create_transaction, transactions_data)) return transactions @@ -484,11 +503,10 @@ def terminate_transactions(self, transaction_ids: List[str]) -> List[MemgraphTer query = ( "TERMINATE TRANSACTIONS " + ", ".join([f"'{transaction_id}'" for transaction_id in transaction_ids]) + ";" ) - print(query) + terminated_transactions = [] - results = self.execute_and_fetch(query) + transactions_data = self.execute_and_fetch(query) + + terminated_transactions = list(map(create_terminated_transaction, transactions_data)) - for result in results: - terminated_transactions.append(MemgraphTerminatedTransaction(result["transaction_id"], result["killed"])) - print(terminated_transactions) return terminated_transactions diff --git a/tests/ogm/test_transactions.py b/tests/ogm/test_transactions.py index f304a8bb..c814eb10 100644 --- a/tests/ogm/test_transactions.py +++ b/tests/ogm/test_transactions.py @@ -5,3 +5,10 @@ def test_get_transactions(memgraph): assert result[0].transaction_id != "" assert result[0].query == ["SHOW TRANSACTIONS;"] assert result[0].metadata == {} + + +def test_terminate_transactions(memgraph): + result = memgraph.get_transactions() + terminated_transactions = memgraph.terminate_transactions([result[0].transaction_id]) + assert terminated_transactions[0].killed is False + assert terminated_transactions[0].transaction_id == result[0].transaction_id From d2d53cc66a5ad3f688ff1ce58a1ffbded009da71 Mon Sep 17 00:00:00 2001 From: katarinasupe Date: Tue, 9 Jul 2024 12:49:08 +0200 Subject: [PATCH 5/5] Delete unnecessary variable init --- gqlalchemy/vendors/memgraph.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gqlalchemy/vendors/memgraph.py b/gqlalchemy/vendors/memgraph.py index 13ec5eb2..6e8dc1ad 100644 --- a/gqlalchemy/vendors/memgraph.py +++ b/gqlalchemy/vendors/memgraph.py @@ -504,7 +504,6 @@ def terminate_transactions(self, transaction_ids: List[str]) -> List[MemgraphTer "TERMINATE TRANSACTIONS " + ", ".join([f"'{transaction_id}'" for transaction_id in transaction_ids]) + ";" ) - terminated_transactions = [] transactions_data = self.execute_and_fetch(query) terminated_transactions = list(map(create_terminated_transaction, transactions_data))