|
23 | 23 | from google.cloud.spanner_dbapi.parse_utils import _get_statement_type |
24 | 24 | from google.cloud.spanner_dbapi.parsed_statement import ( |
25 | 25 | StatementType, |
| 26 | + AutocommitDmlMode, |
26 | 27 | ) |
27 | 28 | from google.cloud.spanner_dbapi.partition_helper import PartitionId |
28 | 29 | from google.cloud.spanner_dbapi.parsed_statement import ParsedStatement, Statement |
@@ -116,6 +117,7 @@ def __init__(self, instance, database=None, read_only=False): |
116 | 117 | self._batch_mode = BatchMode.NONE |
117 | 118 | self._batch_dml_executor: BatchDmlExecutor = None |
118 | 119 | self._transaction_helper = TransactionRetryHelper(self) |
| 120 | + self._autocommit_dml_mode: AutocommitDmlMode = AutocommitDmlMode.TRANSACTIONAL |
119 | 121 |
|
120 | 122 | @property |
121 | 123 | def spanner_client(self): |
@@ -167,6 +169,23 @@ def database(self): |
167 | 169 | """ |
168 | 170 | return self._database |
169 | 171 |
|
| 172 | + @property |
| 173 | + def autocommit_dml_mode(self): |
| 174 | + """Modes for executing DML statements in autocommit mode for this connection. |
| 175 | +
|
| 176 | + The DML autocommit modes are: |
| 177 | + 1) TRANSACTIONAL - DML statements are executed as single read-write transaction. |
| 178 | + After successful execution, the DML statement is guaranteed to have been applied |
| 179 | + exactly once to the database. |
| 180 | +
|
| 181 | + 2) PARTITIONED_NON_ATOMIC - DML statements are executed as partitioned DML transactions. |
| 182 | + If an error occurs during the execution of the DML statement, it is possible that the |
| 183 | + statement has been applied to some but not all of the rows specified in the statement. |
| 184 | +
|
| 185 | + :rtype: :class:`~google.cloud.spanner_dbapi.parsed_statement.AutocommitDmlMode` |
| 186 | + """ |
| 187 | + return self._autocommit_dml_mode |
| 188 | + |
170 | 189 | @property |
171 | 190 | @deprecated( |
172 | 191 | reason="This method is deprecated. Use _spanner_transaction_started field" |
@@ -577,6 +596,37 @@ def run_partitioned_query( |
577 | 596 | partitioned_query, statement.params, statement.param_types |
578 | 597 | ) |
579 | 598 |
|
| 599 | + @check_not_closed |
| 600 | + def _set_autocommit_dml_mode( |
| 601 | + self, |
| 602 | + parsed_statement: ParsedStatement, |
| 603 | + ): |
| 604 | + autocommit_dml_mode_str = parsed_statement.client_side_statement_params[0] |
| 605 | + autocommit_dml_mode = AutocommitDmlMode[autocommit_dml_mode_str.upper()] |
| 606 | + self.set_autocommit_dml_mode(autocommit_dml_mode) |
| 607 | + |
| 608 | + def set_autocommit_dml_mode( |
| 609 | + self, |
| 610 | + autocommit_dml_mode, |
| 611 | + ): |
| 612 | + """ |
| 613 | + Sets the mode for executing DML statements in autocommit mode for this connection. |
| 614 | + This mode is only used when the connection is in autocommit mode, and may only |
| 615 | + be set while the transaction is in autocommit mode and not in a temporary transaction. |
| 616 | + """ |
| 617 | + |
| 618 | + if self._client_transaction_started is True: |
| 619 | + raise ProgrammingError( |
| 620 | + "Cannot set autocommit DML mode while not in autocommit mode or while a transaction is active." |
| 621 | + ) |
| 622 | + if self.read_only is True: |
| 623 | + raise ProgrammingError( |
| 624 | + "Cannot set autocommit DML mode for a read-only connection." |
| 625 | + ) |
| 626 | + if self._batch_mode is not BatchMode.NONE: |
| 627 | + raise ProgrammingError("Cannot set autocommit DML mode while in a batch.") |
| 628 | + self._autocommit_dml_mode = autocommit_dml_mode |
| 629 | + |
580 | 630 | def _partitioned_query_validation(self, partitioned_query, statement): |
581 | 631 | if _get_statement_type(Statement(partitioned_query)) is not StatementType.QUERY: |
582 | 632 | raise ProgrammingError( |
|
0 commit comments