SQLAlchemy 2.0.47__cp313-cp313t-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. sqlalchemy/__init__.py +283 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +184 -0
  4. sqlalchemy/connectors/asyncio.py +429 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/cyextension/__init__.py +6 -0
  7. sqlalchemy/cyextension/collections.cp313t-win32.pyd +0 -0
  8. sqlalchemy/cyextension/collections.pyx +409 -0
  9. sqlalchemy/cyextension/immutabledict.cp313t-win32.pyd +0 -0
  10. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  11. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  12. sqlalchemy/cyextension/processors.cp313t-win32.pyd +0 -0
  13. sqlalchemy/cyextension/processors.pyx +68 -0
  14. sqlalchemy/cyextension/resultproxy.cp313t-win32.pyd +0 -0
  15. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  16. sqlalchemy/cyextension/util.cp313t-win32.pyd +0 -0
  17. sqlalchemy/cyextension/util.pyx +90 -0
  18. sqlalchemy/dialects/__init__.py +62 -0
  19. sqlalchemy/dialects/_typing.py +30 -0
  20. sqlalchemy/dialects/mssql/__init__.py +88 -0
  21. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  22. sqlalchemy/dialects/mssql/base.py +4093 -0
  23. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  24. sqlalchemy/dialects/mssql/json.py +129 -0
  25. sqlalchemy/dialects/mssql/provision.py +185 -0
  26. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  27. sqlalchemy/dialects/mssql/pyodbc.py +760 -0
  28. sqlalchemy/dialects/mysql/__init__.py +104 -0
  29. sqlalchemy/dialects/mysql/aiomysql.py +250 -0
  30. sqlalchemy/dialects/mysql/asyncmy.py +231 -0
  31. sqlalchemy/dialects/mysql/base.py +3949 -0
  32. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  33. sqlalchemy/dialects/mysql/dml.py +225 -0
  34. sqlalchemy/dialects/mysql/enumerated.py +282 -0
  35. sqlalchemy/dialects/mysql/expression.py +146 -0
  36. sqlalchemy/dialects/mysql/json.py +91 -0
  37. sqlalchemy/dialects/mysql/mariadb.py +72 -0
  38. sqlalchemy/dialects/mysql/mariadbconnector.py +322 -0
  39. sqlalchemy/dialects/mysql/mysqlconnector.py +302 -0
  40. sqlalchemy/dialects/mysql/mysqldb.py +314 -0
  41. sqlalchemy/dialects/mysql/provision.py +153 -0
  42. sqlalchemy/dialects/mysql/pymysql.py +158 -0
  43. sqlalchemy/dialects/mysql/pyodbc.py +157 -0
  44. sqlalchemy/dialects/mysql/reflection.py +727 -0
  45. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  46. sqlalchemy/dialects/mysql/types.py +835 -0
  47. sqlalchemy/dialects/oracle/__init__.py +81 -0
  48. sqlalchemy/dialects/oracle/base.py +3802 -0
  49. sqlalchemy/dialects/oracle/cx_oracle.py +1555 -0
  50. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  51. sqlalchemy/dialects/oracle/oracledb.py +941 -0
  52. sqlalchemy/dialects/oracle/provision.py +297 -0
  53. sqlalchemy/dialects/oracle/types.py +316 -0
  54. sqlalchemy/dialects/oracle/vector.py +365 -0
  55. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  56. sqlalchemy/dialects/postgresql/_psycopg_common.py +189 -0
  57. sqlalchemy/dialects/postgresql/array.py +519 -0
  58. sqlalchemy/dialects/postgresql/asyncpg.py +1284 -0
  59. sqlalchemy/dialects/postgresql/base.py +5378 -0
  60. sqlalchemy/dialects/postgresql/dml.py +339 -0
  61. sqlalchemy/dialects/postgresql/ext.py +540 -0
  62. sqlalchemy/dialects/postgresql/hstore.py +406 -0
  63. sqlalchemy/dialects/postgresql/json.py +404 -0
  64. sqlalchemy/dialects/postgresql/named_types.py +524 -0
  65. sqlalchemy/dialects/postgresql/operators.py +129 -0
  66. sqlalchemy/dialects/postgresql/pg8000.py +669 -0
  67. sqlalchemy/dialects/postgresql/pg_catalog.py +326 -0
  68. sqlalchemy/dialects/postgresql/provision.py +183 -0
  69. sqlalchemy/dialects/postgresql/psycopg.py +862 -0
  70. sqlalchemy/dialects/postgresql/psycopg2.py +892 -0
  71. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  72. sqlalchemy/dialects/postgresql/ranges.py +1031 -0
  73. sqlalchemy/dialects/postgresql/types.py +313 -0
  74. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  75. sqlalchemy/dialects/sqlite/aiosqlite.py +482 -0
  76. sqlalchemy/dialects/sqlite/base.py +3056 -0
  77. sqlalchemy/dialects/sqlite/dml.py +263 -0
  78. sqlalchemy/dialects/sqlite/json.py +92 -0
  79. sqlalchemy/dialects/sqlite/provision.py +229 -0
  80. sqlalchemy/dialects/sqlite/pysqlcipher.py +157 -0
  81. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  82. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  83. sqlalchemy/engine/__init__.py +62 -0
  84. sqlalchemy/engine/_py_processors.py +136 -0
  85. sqlalchemy/engine/_py_row.py +128 -0
  86. sqlalchemy/engine/_py_util.py +74 -0
  87. sqlalchemy/engine/base.py +3390 -0
  88. sqlalchemy/engine/characteristics.py +155 -0
  89. sqlalchemy/engine/create.py +893 -0
  90. sqlalchemy/engine/cursor.py +2298 -0
  91. sqlalchemy/engine/default.py +2394 -0
  92. sqlalchemy/engine/events.py +965 -0
  93. sqlalchemy/engine/interfaces.py +3471 -0
  94. sqlalchemy/engine/mock.py +134 -0
  95. sqlalchemy/engine/processors.py +61 -0
  96. sqlalchemy/engine/reflection.py +2102 -0
  97. sqlalchemy/engine/result.py +2399 -0
  98. sqlalchemy/engine/row.py +400 -0
  99. sqlalchemy/engine/strategies.py +16 -0
  100. sqlalchemy/engine/url.py +924 -0
  101. sqlalchemy/engine/util.py +167 -0
  102. sqlalchemy/event/__init__.py +26 -0
  103. sqlalchemy/event/api.py +220 -0
  104. sqlalchemy/event/attr.py +676 -0
  105. sqlalchemy/event/base.py +472 -0
  106. sqlalchemy/event/legacy.py +258 -0
  107. sqlalchemy/event/registry.py +390 -0
  108. sqlalchemy/events.py +17 -0
  109. sqlalchemy/exc.py +832 -0
  110. sqlalchemy/ext/__init__.py +11 -0
  111. sqlalchemy/ext/associationproxy.py +2027 -0
  112. sqlalchemy/ext/asyncio/__init__.py +25 -0
  113. sqlalchemy/ext/asyncio/base.py +281 -0
  114. sqlalchemy/ext/asyncio/engine.py +1471 -0
  115. sqlalchemy/ext/asyncio/exc.py +21 -0
  116. sqlalchemy/ext/asyncio/result.py +965 -0
  117. sqlalchemy/ext/asyncio/scoping.py +1599 -0
  118. sqlalchemy/ext/asyncio/session.py +1947 -0
  119. sqlalchemy/ext/automap.py +1701 -0
  120. sqlalchemy/ext/baked.py +570 -0
  121. sqlalchemy/ext/compiler.py +600 -0
  122. sqlalchemy/ext/declarative/__init__.py +65 -0
  123. sqlalchemy/ext/declarative/extensions.py +564 -0
  124. sqlalchemy/ext/horizontal_shard.py +478 -0
  125. sqlalchemy/ext/hybrid.py +1535 -0
  126. sqlalchemy/ext/indexable.py +364 -0
  127. sqlalchemy/ext/instrumentation.py +450 -0
  128. sqlalchemy/ext/mutable.py +1085 -0
  129. sqlalchemy/ext/mypy/__init__.py +6 -0
  130. sqlalchemy/ext/mypy/apply.py +324 -0
  131. sqlalchemy/ext/mypy/decl_class.py +515 -0
  132. sqlalchemy/ext/mypy/infer.py +590 -0
  133. sqlalchemy/ext/mypy/names.py +335 -0
  134. sqlalchemy/ext/mypy/plugin.py +303 -0
  135. sqlalchemy/ext/mypy/util.py +357 -0
  136. sqlalchemy/ext/orderinglist.py +439 -0
  137. sqlalchemy/ext/serializer.py +185 -0
  138. sqlalchemy/future/__init__.py +16 -0
  139. sqlalchemy/future/engine.py +15 -0
  140. sqlalchemy/inspection.py +174 -0
  141. sqlalchemy/log.py +288 -0
  142. sqlalchemy/orm/__init__.py +171 -0
  143. sqlalchemy/orm/_orm_constructors.py +2661 -0
  144. sqlalchemy/orm/_typing.py +179 -0
  145. sqlalchemy/orm/attributes.py +2845 -0
  146. sqlalchemy/orm/base.py +971 -0
  147. sqlalchemy/orm/bulk_persistence.py +2135 -0
  148. sqlalchemy/orm/clsregistry.py +571 -0
  149. sqlalchemy/orm/collections.py +1627 -0
  150. sqlalchemy/orm/context.py +3334 -0
  151. sqlalchemy/orm/decl_api.py +2004 -0
  152. sqlalchemy/orm/decl_base.py +2192 -0
  153. sqlalchemy/orm/dependency.py +1302 -0
  154. sqlalchemy/orm/descriptor_props.py +1092 -0
  155. sqlalchemy/orm/dynamic.py +300 -0
  156. sqlalchemy/orm/evaluator.py +379 -0
  157. sqlalchemy/orm/events.py +3252 -0
  158. sqlalchemy/orm/exc.py +237 -0
  159. sqlalchemy/orm/identity.py +302 -0
  160. sqlalchemy/orm/instrumentation.py +754 -0
  161. sqlalchemy/orm/interfaces.py +1496 -0
  162. sqlalchemy/orm/loading.py +1686 -0
  163. sqlalchemy/orm/mapped_collection.py +557 -0
  164. sqlalchemy/orm/mapper.py +4444 -0
  165. sqlalchemy/orm/path_registry.py +809 -0
  166. sqlalchemy/orm/persistence.py +1788 -0
  167. sqlalchemy/orm/properties.py +935 -0
  168. sqlalchemy/orm/query.py +3459 -0
  169. sqlalchemy/orm/relationships.py +3508 -0
  170. sqlalchemy/orm/scoping.py +2148 -0
  171. sqlalchemy/orm/session.py +5280 -0
  172. sqlalchemy/orm/state.py +1168 -0
  173. sqlalchemy/orm/state_changes.py +196 -0
  174. sqlalchemy/orm/strategies.py +3470 -0
  175. sqlalchemy/orm/strategy_options.py +2568 -0
  176. sqlalchemy/orm/sync.py +164 -0
  177. sqlalchemy/orm/unitofwork.py +796 -0
  178. sqlalchemy/orm/util.py +2403 -0
  179. sqlalchemy/orm/writeonly.py +674 -0
  180. sqlalchemy/pool/__init__.py +44 -0
  181. sqlalchemy/pool/base.py +1524 -0
  182. sqlalchemy/pool/events.py +375 -0
  183. sqlalchemy/pool/impl.py +588 -0
  184. sqlalchemy/py.typed +0 -0
  185. sqlalchemy/schema.py +69 -0
  186. sqlalchemy/sql/__init__.py +145 -0
  187. sqlalchemy/sql/_dml_constructors.py +132 -0
  188. sqlalchemy/sql/_elements_constructors.py +1872 -0
  189. sqlalchemy/sql/_orm_types.py +20 -0
  190. sqlalchemy/sql/_py_util.py +75 -0
  191. sqlalchemy/sql/_selectable_constructors.py +763 -0
  192. sqlalchemy/sql/_typing.py +482 -0
  193. sqlalchemy/sql/annotation.py +587 -0
  194. sqlalchemy/sql/base.py +2293 -0
  195. sqlalchemy/sql/cache_key.py +1057 -0
  196. sqlalchemy/sql/coercions.py +1404 -0
  197. sqlalchemy/sql/compiler.py +8081 -0
  198. sqlalchemy/sql/crud.py +1752 -0
  199. sqlalchemy/sql/ddl.py +1444 -0
  200. sqlalchemy/sql/default_comparator.py +551 -0
  201. sqlalchemy/sql/dml.py +1850 -0
  202. sqlalchemy/sql/elements.py +5589 -0
  203. sqlalchemy/sql/events.py +458 -0
  204. sqlalchemy/sql/expression.py +159 -0
  205. sqlalchemy/sql/functions.py +2158 -0
  206. sqlalchemy/sql/lambdas.py +1442 -0
  207. sqlalchemy/sql/naming.py +209 -0
  208. sqlalchemy/sql/operators.py +2623 -0
  209. sqlalchemy/sql/roles.py +323 -0
  210. sqlalchemy/sql/schema.py +6222 -0
  211. sqlalchemy/sql/selectable.py +7265 -0
  212. sqlalchemy/sql/sqltypes.py +3930 -0
  213. sqlalchemy/sql/traversals.py +1024 -0
  214. sqlalchemy/sql/type_api.py +2368 -0
  215. sqlalchemy/sql/util.py +1485 -0
  216. sqlalchemy/sql/visitors.py +1164 -0
  217. sqlalchemy/testing/__init__.py +96 -0
  218. sqlalchemy/testing/assertions.py +994 -0
  219. sqlalchemy/testing/assertsql.py +520 -0
  220. sqlalchemy/testing/asyncio.py +135 -0
  221. sqlalchemy/testing/config.py +434 -0
  222. sqlalchemy/testing/engines.py +483 -0
  223. sqlalchemy/testing/entities.py +117 -0
  224. sqlalchemy/testing/exclusions.py +476 -0
  225. sqlalchemy/testing/fixtures/__init__.py +28 -0
  226. sqlalchemy/testing/fixtures/base.py +384 -0
  227. sqlalchemy/testing/fixtures/mypy.py +332 -0
  228. sqlalchemy/testing/fixtures/orm.py +227 -0
  229. sqlalchemy/testing/fixtures/sql.py +482 -0
  230. sqlalchemy/testing/pickleable.py +155 -0
  231. sqlalchemy/testing/plugin/__init__.py +6 -0
  232. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  233. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  234. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  235. sqlalchemy/testing/profiling.py +329 -0
  236. sqlalchemy/testing/provision.py +603 -0
  237. sqlalchemy/testing/requirements.py +1945 -0
  238. sqlalchemy/testing/schema.py +198 -0
  239. sqlalchemy/testing/suite/__init__.py +19 -0
  240. sqlalchemy/testing/suite/test_cte.py +237 -0
  241. sqlalchemy/testing/suite/test_ddl.py +389 -0
  242. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  243. sqlalchemy/testing/suite/test_dialect.py +776 -0
  244. sqlalchemy/testing/suite/test_insert.py +630 -0
  245. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  246. sqlalchemy/testing/suite/test_results.py +504 -0
  247. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  248. sqlalchemy/testing/suite/test_select.py +2010 -0
  249. sqlalchemy/testing/suite/test_sequence.py +317 -0
  250. sqlalchemy/testing/suite/test_types.py +2147 -0
  251. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  252. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  253. sqlalchemy/testing/util.py +535 -0
  254. sqlalchemy/testing/warnings.py +52 -0
  255. sqlalchemy/types.py +74 -0
  256. sqlalchemy/util/__init__.py +162 -0
  257. sqlalchemy/util/_collections.py +712 -0
  258. sqlalchemy/util/_concurrency_py3k.py +288 -0
  259. sqlalchemy/util/_has_cy.py +40 -0
  260. sqlalchemy/util/_py_collections.py +541 -0
  261. sqlalchemy/util/compat.py +421 -0
  262. sqlalchemy/util/concurrency.py +110 -0
  263. sqlalchemy/util/deprecations.py +401 -0
  264. sqlalchemy/util/langhelpers.py +2203 -0
  265. sqlalchemy/util/preloaded.py +150 -0
  266. sqlalchemy/util/queue.py +322 -0
  267. sqlalchemy/util/tool_support.py +201 -0
  268. sqlalchemy/util/topological.py +120 -0
  269. sqlalchemy/util/typing.py +734 -0
  270. sqlalchemy-2.0.47.dist-info/METADATA +243 -0
  271. sqlalchemy-2.0.47.dist-info/RECORD +274 -0
  272. sqlalchemy-2.0.47.dist-info/WHEEL +5 -0
  273. sqlalchemy-2.0.47.dist-info/licenses/LICENSE +19 -0
  274. sqlalchemy-2.0.47.dist-info/top_level.txt +1 -0
@@ -0,0 +1,258 @@
1
+ # testing/suite/test_rowcount.py
2
+ # Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+ # mypy: ignore-errors
8
+
9
+ from sqlalchemy import bindparam
10
+ from sqlalchemy import Column
11
+ from sqlalchemy import Integer
12
+ from sqlalchemy import MetaData
13
+ from sqlalchemy import select
14
+ from sqlalchemy import String
15
+ from sqlalchemy import Table
16
+ from sqlalchemy import testing
17
+ from sqlalchemy import text
18
+ from sqlalchemy.testing import eq_
19
+ from sqlalchemy.testing import fixtures
20
+
21
+
22
+ class RowCountTest(fixtures.TablesTest):
23
+ """test rowcount functionality"""
24
+
25
+ __requires__ = ("sane_rowcount",)
26
+ __backend__ = True
27
+
28
+ @classmethod
29
+ def define_tables(cls, metadata):
30
+ Table(
31
+ "employees",
32
+ metadata,
33
+ Column(
34
+ "employee_id",
35
+ Integer,
36
+ autoincrement=False,
37
+ primary_key=True,
38
+ ),
39
+ Column("name", String(50)),
40
+ Column("department", String(1)),
41
+ )
42
+
43
+ @classmethod
44
+ def insert_data(cls, connection):
45
+ cls.data = data = [
46
+ ("Angela", "A"),
47
+ ("Andrew", "A"),
48
+ ("Anand", "A"),
49
+ ("Bob", "B"),
50
+ ("Bobette", "B"),
51
+ ("Buffy", "B"),
52
+ ("Charlie", "C"),
53
+ ("Cynthia", "C"),
54
+ ("Chris", "C"),
55
+ ]
56
+
57
+ employees_table = cls.tables.employees
58
+ connection.execute(
59
+ employees_table.insert(),
60
+ [
61
+ {"employee_id": i, "name": n, "department": d}
62
+ for i, (n, d) in enumerate(data)
63
+ ],
64
+ )
65
+
66
+ def test_basic(self, connection):
67
+ employees_table = self.tables.employees
68
+ s = select(
69
+ employees_table.c.name, employees_table.c.department
70
+ ).order_by(employees_table.c.employee_id)
71
+ rows = connection.execute(s).fetchall()
72
+
73
+ eq_(rows, self.data)
74
+
75
+ @testing.variation("statement", ["update", "delete", "insert", "select"])
76
+ @testing.variation("close_first", [True, False])
77
+ def test_non_rowcount_scenarios_no_raise(
78
+ self, connection, statement, close_first
79
+ ):
80
+ employees_table = self.tables.employees
81
+
82
+ # WHERE matches 3, 3 rows changed
83
+ department = employees_table.c.department
84
+
85
+ if statement.update:
86
+ r = connection.execute(
87
+ employees_table.update().where(department == "C"),
88
+ {"department": "Z"},
89
+ )
90
+ elif statement.delete:
91
+ r = connection.execute(
92
+ employees_table.delete().where(department == "C"),
93
+ {"department": "Z"},
94
+ )
95
+ elif statement.insert:
96
+ r = connection.execute(
97
+ employees_table.insert(),
98
+ [
99
+ {"employee_id": 25, "name": "none 1", "department": "X"},
100
+ {"employee_id": 26, "name": "none 2", "department": "Z"},
101
+ {"employee_id": 27, "name": "none 3", "department": "Z"},
102
+ ],
103
+ )
104
+ elif statement.select:
105
+ s = select(
106
+ employees_table.c.name, employees_table.c.department
107
+ ).where(employees_table.c.department == "C")
108
+ r = connection.execute(s)
109
+ r.all()
110
+ else:
111
+ statement.fail()
112
+
113
+ if close_first:
114
+ r.close()
115
+
116
+ assert r.rowcount in (-1, 3)
117
+
118
+ def test_update_rowcount1(self, connection):
119
+ employees_table = self.tables.employees
120
+
121
+ # WHERE matches 3, 3 rows changed
122
+ department = employees_table.c.department
123
+ r = connection.execute(
124
+ employees_table.update().where(department == "C"),
125
+ {"department": "Z"},
126
+ )
127
+ assert r.rowcount == 3
128
+
129
+ def test_update_rowcount2(self, connection):
130
+ employees_table = self.tables.employees
131
+
132
+ # WHERE matches 3, 0 rows changed
133
+ department = employees_table.c.department
134
+
135
+ r = connection.execute(
136
+ employees_table.update().where(department == "C"),
137
+ {"department": "C"},
138
+ )
139
+ eq_(r.rowcount, 3)
140
+
141
+ @testing.variation("implicit_returning", [True, False])
142
+ @testing.variation(
143
+ "dml",
144
+ [
145
+ ("update", testing.requires.update_returning),
146
+ ("delete", testing.requires.delete_returning),
147
+ ],
148
+ )
149
+ def test_update_delete_rowcount_return_defaults(
150
+ self, connection, implicit_returning, dml
151
+ ):
152
+ """note this test should succeed for all RETURNING backends
153
+ as of 2.0. In
154
+ Idf28379f8705e403a3c6a937f6a798a042ef2540 we changed rowcount to use
155
+ len(rows) when we have implicit returning
156
+
157
+ """
158
+
159
+ if implicit_returning:
160
+ employees_table = self.tables.employees
161
+ else:
162
+ employees_table = Table(
163
+ "employees",
164
+ MetaData(),
165
+ Column(
166
+ "employee_id",
167
+ Integer,
168
+ autoincrement=False,
169
+ primary_key=True,
170
+ ),
171
+ Column("name", String(50)),
172
+ Column("department", String(1)),
173
+ implicit_returning=False,
174
+ )
175
+
176
+ department = employees_table.c.department
177
+
178
+ if dml.update:
179
+ stmt = (
180
+ employees_table.update()
181
+ .where(department == "C")
182
+ .values(name=employees_table.c.department + "Z")
183
+ .return_defaults()
184
+ )
185
+ elif dml.delete:
186
+ stmt = (
187
+ employees_table.delete()
188
+ .where(department == "C")
189
+ .return_defaults()
190
+ )
191
+ else:
192
+ dml.fail()
193
+
194
+ r = connection.execute(stmt)
195
+ eq_(r.rowcount, 3)
196
+
197
+ def test_raw_sql_rowcount(self, connection):
198
+ # test issue #3622, make sure eager rowcount is called for text
199
+ result = connection.exec_driver_sql(
200
+ "update employees set department='Z' where department='C'"
201
+ )
202
+ eq_(result.rowcount, 3)
203
+
204
+ def test_text_rowcount(self, connection):
205
+ # test issue #3622, make sure eager rowcount is called for text
206
+ result = connection.execute(
207
+ text("update employees set department='Z' where department='C'")
208
+ )
209
+ eq_(result.rowcount, 3)
210
+
211
+ def test_delete_rowcount(self, connection):
212
+ employees_table = self.tables.employees
213
+
214
+ # WHERE matches 3, 3 rows deleted
215
+ department = employees_table.c.department
216
+ r = connection.execute(
217
+ employees_table.delete().where(department == "C")
218
+ )
219
+ eq_(r.rowcount, 3)
220
+
221
+ @testing.requires.sane_multi_rowcount
222
+ def test_multi_update_rowcount(self, connection):
223
+ employees_table = self.tables.employees
224
+ stmt = (
225
+ employees_table.update()
226
+ .where(employees_table.c.name == bindparam("emp_name"))
227
+ .values(department="C")
228
+ )
229
+
230
+ r = connection.execute(
231
+ stmt,
232
+ [
233
+ {"emp_name": "Bob"},
234
+ {"emp_name": "Cynthia"},
235
+ {"emp_name": "nonexistent"},
236
+ ],
237
+ )
238
+
239
+ eq_(r.rowcount, 2)
240
+
241
+ @testing.requires.sane_multi_rowcount
242
+ def test_multi_delete_rowcount(self, connection):
243
+ employees_table = self.tables.employees
244
+
245
+ stmt = employees_table.delete().where(
246
+ employees_table.c.name == bindparam("emp_name")
247
+ )
248
+
249
+ r = connection.execute(
250
+ stmt,
251
+ [
252
+ {"emp_name": "Bob"},
253
+ {"emp_name": "Cynthia"},
254
+ {"emp_name": "nonexistent"},
255
+ ],
256
+ )
257
+
258
+ eq_(r.rowcount, 2)