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
158185Check 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