Skip to content

Commit 13ed96f

Browse files
committed
Tests: Refactor SQLAlchemy-related doctests into documentation
- doctests/sqlalchemy.rst - sqlalchemy/doctests/{dialect,itests,reflection}.txt
1 parent 1731cc5 commit 13ed96f

File tree

8 files changed

+261
-158
lines changed

8 files changed

+261
-158
lines changed

docs/by-example/index.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ About
1010
This part of the documentation contains examples how to use the CrateDB Python
1111
client, exercising different options and scenarios.
1212

13+
14+
DBAPI, HTTP, and BLOB interfaces
15+
================================
16+
17+
The examples in this section are all about CrateDB's `Python DBAPI`_ interface,
18+
the plain HTTP API interface, and a convenience interface for working with
19+
`blob tables`_. It also details attributes, methods, and behaviors of the
20+
``Connection`` and ``Cursor`` objects.
21+
1322
.. toctree::
1423
:maxdepth: 1
1524

@@ -19,3 +28,25 @@ client, exercising different options and scenarios.
1928
blob
2029
connection
2130
cursor
31+
32+
33+
.. _sqlalchemy-by-example:
34+
35+
SQLAlchemy interface
36+
====================
37+
38+
The examples in this section are all about CrateDB's `SQLAlchemy`_ dialect, and
39+
its corresponding API interfaces, see also :ref:`sqlalchemy-support`.
40+
41+
.. toctree::
42+
:maxdepth: 1
43+
44+
sqlalchemy/getting-started
45+
sqlalchemy/cru
46+
sqlalchemy/inspection-reflection
47+
sqlalchemy/internals
48+
49+
50+
.. _blob tables: https://crate.io/docs/crate/reference/en/latest/general/blobs.html
51+
.. _Python DBAPI: https://peps.python.org/pep-0249/
52+
.. _SQLAlchemy: https://www.sqlalchemy.org/

src/crate/client/sqlalchemy/doctests/itests.txt renamed to docs/by-example/sqlalchemy/cru.rst

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
1-
==================
2-
SQLAlchemy Dialect
3-
==================
1+
========================================
2+
SQLAlchemy: Create, retrieve, and update
3+
========================================
4+
5+
This section of the documentation, related to CrateDB's SQLAlchemy integration,
6+
focuses on showing specific details when querying, inserting, and updating
7+
records. It covers filtering and limiting, insert and update default values,
8+
and updating complex data types with nested Python dictionaries.
9+
10+
.. rubric:: Table of Contents
11+
12+
.. contents::
13+
:local:
14+
15+
16+
Setup
17+
=====
18+
19+
Establish a connection to the database:
420

521
>>> connection = engine.connect()
622

7-
Using the connection to execute a select statement::
23+
24+
Retrieve
25+
========
26+
27+
Using the connection to execute a select statement:
828

929
>>> result = connection.execute('select name from locations order by name')
1030
>>> result.rowcount
@@ -13,33 +33,36 @@ Using the connection to execute a select statement::
1333
>>> result.first()
1434
('Aldebaran',)
1535

16-
Using the ORM to query the locations::
36+
Using the ORM to query the locations:
1737

1838
>>> locations = session.query(Location).order_by('name')
1939
>>> [l.name for l in locations if l is not None][:2]
2040
['Aldebaran', 'Algol']
2141

22-
With limit and offset::
42+
With limit and offset:
2343

2444
>>> locations = session.query(Location).order_by('name').offset(1).limit(2)
2545
>>> [l.name for l in locations if l is not None]
2646
['Algol', 'Allosimanius Syneca']
2747

28-
With filter::
48+
With filter:
2949

3050
>>> location = session.query(Location).filter_by(name='Algol').one()
3151
>>> location.name
3252
'Algol'
3353

34-
Order by::
54+
Order by:
3555

3656
>>> locations = session.query(Location).filter(Location.name != None).order_by(sa.desc(Location.name))
3757
>>> locations = locations.limit(2)
3858
>>> [l.name for l in locations]
3959
['Outer Eastern Rim', 'North West Ripple']
4060

4161

42-
Insert a new location::
62+
Create
63+
======
64+
65+
Insert a new location:
4366

4467
>>> location = Location()
4568
>>> location.name = 'Earth'
@@ -53,19 +76,19 @@ Refresh "locations" table:
5376

5477
>>> _ = connection.execute("REFRESH TABLE locations")
5578

56-
Inserted location is available::
79+
Inserted location is available:
5780

5881
>>> location = session.query(Location).filter_by(name='Earth').one()
5982
>>> location.name
6083
'Earth'
6184

62-
Retrieve the location from the database::
85+
Retrieve the location from the database:
6386

6487
>>> session.refresh(location)
6588
>>> location.name
6689
'Earth'
6790

68-
Date should have been set at the insert due to default value via python method::
91+
Date should have been set at the insert due to default value via Python method:
6992

7093
>>> from datetime import datetime
7194
>>> now = datetime.utcnow()
@@ -83,7 +106,7 @@ Date should have been set at the insert due to default value via python method::
83106
>>> (now - location.datetime_tz).seconds < 4
84107
True
85108

86-
Verify the return type of date and datetime::
109+
Verify the return type of date and datetime:
87110

88111
>>> type(location.date)
89112
<class 'datetime.date'>
@@ -94,16 +117,20 @@ Verify the return type of date and datetime::
94117
>>> type(location.datetime_notz)
95118
<class 'datetime.datetime'>
96119

97-
the location also has a date and datetime property which both are nullable and
98-
aren't set when the row is inserted as there is no default method::
120+
The location also has a date and datetime property which both are nullable and
121+
aren't set when the row is inserted as there is no default method:
99122

100123
>>> location.nullable_datetime is None
101124
True
102125

103126
>>> location.nullable_date is None
104127
True
105128

106-
The datetime and date can be set using a update statement::
129+
130+
Update
131+
======
132+
133+
The datetime and date can be set using a update statement:
107134

108135
>>> location.nullable_date = datetime.utcnow().date()
109136
>>> location.nullable_datetime = datetime.utcnow()
@@ -113,30 +140,30 @@ Refresh "locations" table:
113140

114141
>>> _ = connection.execute("REFRESH TABLE locations")
115142

116-
Boolean values get set natively::
143+
Boolean values get set natively:
117144

118145
>>> location.flag
119146
True
120147

121-
Reload the object from the db::
148+
Reload the object from the db:
122149

123150
>>> session.refresh(location)
124151

125-
And verify that the date and datetime was persisted::
152+
And verify that the date and datetime was persisted:
126153

127154
>>> location.nullable_datetime is not None
128155
True
129156

130157
>>> location.nullable_date is not None
131158
True
132159

133-
Update one Location via raw sql::
160+
Update a record using SQL:
134161

135162
>>> result = connection.execute("update locations set kind='Heimat' where name='Earth'")
136163
>>> result.rowcount
137164
1
138165

139-
Update multiple Locations::
166+
Update multiple records:
140167

141168
>>> for x in range(10):
142169
... loc = Location()
@@ -145,7 +172,7 @@ Update multiple Locations::
145172
... session.add(loc)
146173
... session.flush()
147174

148-
Refresh "locations" table:
175+
Refresh table:
149176

150177
>>> _ = connection.execute("REFRESH TABLE locations")
151178

@@ -156,7 +183,7 @@ Query database:
156183
10
157184

158185
Check that number of affected documents of update without ``where-clause`` matches number of all
159-
documents in the table::
186+
documents in the table:
160187

161188
>>> result = connection.execute(u"update locations set kind='Überall'")
162189
>>> result.rowcount == connection.execute("select * from locations limit 100").rowcount
@@ -168,7 +195,7 @@ Refresh "locations" table:
168195

169196
>>> _ = connection.execute("REFRESH TABLE locations")
170197

171-
Test that objects can be used as list too::
198+
Test that objects can be used as list too:
172199

173200
>>> location = session.query(Location).filter_by(name='Folfanga').one()
174201
>>> location.details = [{'size': 'huge'}, {'clima': 'cold'}]
@@ -179,7 +206,7 @@ Test that objects can be used as list too::
179206
>>> location.details
180207
[{'size': 'huge'}, {'clima': 'cold'}]
181208

182-
Update the clima::
209+
Update the record:
183210

184211
>>> location.details[1] = {'clima': 'hot'}
185212

@@ -189,7 +216,7 @@ Update the clima::
189216
>>> location.details
190217
[{'size': 'huge'}, {'clima': 'hot'}]
191218

192-
Reset the clima::
219+
Reset the record:
193220

194221
>>> location.details = []
195222
>>> session.commit()
@@ -198,7 +225,7 @@ Reset the clima::
198225
>>> location.details
199226
[]
200227

201-
test updated nested dict::
228+
Update nested dictionary:
202229

203230
>>> from crate.client.sqlalchemy.types import Craty
204231
>>> class Character(Base):

0 commit comments

Comments
 (0)