You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from sqlalchemy import MetaData, Table, create_engine, select
82
81
@@ -90,16 +89,16 @@ with engine.begin() as connection:
90
89
print(row)
91
90
```
92
91
93
-
Migration
94
-
-----------
92
+
## Migration
93
+
95
94
SQLAlchemy uses [Alembic](https://alembic.sqlalchemy.org/en/latest/#) tool to organize database migrations.
96
95
97
96
**Warning!**
98
97
A migration script can produce a lot of DDL statements. If each of the statements are executed separately, performance issues can occur. To avoid these, it's highly recommended to use the [Alembic batch context](https://alembic.sqlalchemy.org/en/latest/batch.html) feature to pack DDL statements into groups of statements.
99
98
100
-
Features and limitations
101
-
-----------
102
-
**Interleaved tables**
99
+
## Features and limitations
100
+
101
+
### Interleaved tables
103
102
Cloud Spanner dialect includes two dialect-specific arguments for `Table` constructor, which help to define interleave relations:
104
103
`spanner_interleave_in` - a parent table name
105
104
`spanner_inverleave_on_delete_cascade` - a flag specifying if `ON DELETE CASCADE` statement must be used for the interleave relation
@@ -126,7 +125,7 @@ client = Table(
126
125
client.create(engine)
127
126
```
128
127
129
-
**Unique constraints**
128
+
### Unique constraints
130
129
Cloud Spanner doesn't support direct UNIQUE constraints creation. In order to achieve column values uniqueness UNIQUE indexes should be used.
131
130
132
131
Instead of direct UNIQUE constraint creation:
@@ -147,7 +146,7 @@ Table(
147
146
Index("uix_1", "col1", unique=True),
148
147
)
149
148
```
150
-
**Autocommit mode**
149
+
### Autocommit mode
151
150
Spanner dialect supports both `SERIALIZABLE` and `AUTOCOMMIT` isolation levels. `SERIALIZABLE` is the default one, where transactions need to be committed manually. `AUTOCOMMIT` mode corresponds to automatically committing of a query right in its execution time.
152
151
153
152
Isolation level change example:
@@ -158,7 +157,7 @@ eng = create_engine("spanner:///projects/project-id/instances/instance-id/databa
By default, transactions produced by a Spanner connection are in ReadWrite mode. However, some applications require an ability to grant ReadOnly access to users/methods; for these cases Spanner dialect supports the `read_only` execution option, which switches a connection into ReadOnly mode:
163
162
```python
164
163
with engine.connect().execution_options(read_only=True) as connection:
@@ -168,13 +167,13 @@ Note that execution options are applied lazily - on the `execute()` method call,
168
167
169
168
ReadOnly/ReadWrite mode of a connection can't be changed while a transaction is in progress - first you must commit or rollback it.
170
169
171
-
**DDL and transactions**
170
+
### DDL and transactions
172
171
DDL statements are executed outside the regular transactions mechanism, which means DDL statements will not be rolled back on normal transaction rollback.
173
172
174
-
**Dropping a table**
173
+
### Dropping a table
175
174
Cloud Spanner, by default, doesn't drop tables, which have secondary indexes and/or foreign key constraints. In Spanner dialect for SQLAlchemy, however, this restriction is omitted - if a table you are trying to delete has indexes/foreign keys, they will be dropped automatically right before dropping the table.
176
175
177
-
**Data types**
176
+
### Data types
178
177
Data types table mapping SQLAlchemy types to Cloud Spanner types:
179
178
180
179
| SQLAlchemy | Spanner |
@@ -193,14 +192,13 @@ Data types table mapping SQLAlchemy types to Cloud Spanner types:
193
192
| NUMERIC | NUMERIC |
194
193
195
194
196
-
**Other limitations**
195
+
### Other limitations
197
196
- WITH RECURSIVE statement is not supported.
198
197
- Named schemas are not supported.
199
198
- Temporary tables are not supported, real tables are used instead.
200
199
- Numeric type dimensions (scale and precision) are constant. See the [docs](https://cloud.google.com/spanner/docs/data-types#numeric_types).
201
200
202
-
Best practices
203
-
-----------
201
+
## Best practices
204
202
When a SQLAlchemy function is called, a new connection to a database is established and a Spanner session object is fetched. In case of connectionless execution these fetches are done for every `execute()` call, which can cause a significant latency. To avoid initiating a Spanner session on every `execute()` call it's recommended to write code in connection-bounded fashion. Once a `Connection()` object is explicitly initiated, it fetches a Spanner session object and uses it for all the following calls made on this `Connection()` object.
205
203
206
204
Non-optimal connectionless use:
@@ -216,8 +214,8 @@ with engine.begin() as connection:
216
214
```
217
215
Connectionless way of use is also deprecated since SQLAlchemy 2.0 and soon will be removed (see in [SQLAlchemy docs](https://docs.sqlalchemy.org/en/14/core/connections.html#connectionless-execution-implicit-execution)).
218
216
219
-
Running tests
220
-
------------
217
+
## Running tests
218
+
221
219
Spanner dialect includes a compliance, migration and unit test suite. To run the tests the `nox` package commands can be used:
222
220
```
223
221
# Run the whole suite
@@ -226,11 +224,10 @@ $ nox
226
224
# Run a particular test session
227
225
$ nox -s migration_test
228
226
```
229
-
**Running tests on Spanner emulator**
227
+
### Running tests on Spanner emulator
230
228
The dialect test suite can be runned on [Spanner emulator](https://cloud.google.com/spanner/docs/emulator). Several tests, relating to `NULL` values of data types, are skipped when executed on emulator.
231
229
232
-
Contributing
233
-
------------
230
+
## Contributing
234
231
235
232
Contributions to this library are welcome and encouraged. Please report issues, file feature requests, and send pull requests. See [CONTRIBUTING](https://github.com/cloudspannerecosystem/python-spanner-sqlalchemy/blob/main/contributing.md) for more information on how to get
0 commit comments