codekingpro/portable-devtools
114k
1# testing/suite/test_update_delete.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
9from .. import fixtures
10from ..assertions import eq_
11from ..schema import Column
12from ..schema import Table
13from ... import Integer
14from ... import String
15from ... import testing
16
17
18class SimpleUpdateDeleteTest(fixtures.TablesTest):
19 run_deletes = "each"
20 __requires__ = ("sane_rowcount",)
21 __sparse_driver_backend__ = True
22
23 @classmethod
24 def define_tables(cls, metadata):
25 Table(
26 "plain_pk",
27 metadata,
28 Column("id", Integer, primary_key=True),
29 Column("data", String(50)),
30 )
31
32 @classmethod
33 def insert_data(cls, connection):
34 connection.execute(
35 cls.tables.plain_pk.insert(),
36 [
37 {"id": 1, "data": "d1"},
38 {"id": 2, "data": "d2"},
39 {"id": 3, "data": "d3"},
40 ],
41 )
42
43 def test_update(self, connection):
44 t = self.tables.plain_pk
45 r = connection.execute(
46 t.update().where(t.c.id == 2), dict(data="d2_new")
47 )
48 assert not r.is_insert
49 assert not r.returns_rows
50 assert r.rowcount == 1
51
52 eq_(
53 connection.execute(t.select().order_by(t.c.id)).fetchall(),
54 [(1, "d1"), (2, "d2_new"), (3, "d3")],
55 )
56
57 def test_delete(self, connection):
58 t = self.tables.plain_pk
59 r = connection.execute(t.delete().where(t.c.id == 2))
60 assert not r.is_insert
61 assert not r.returns_rows
62 assert r.rowcount == 1
63 eq_(
64 connection.execute(t.select().order_by(t.c.id)).fetchall(),
65 [(1, "d1"), (3, "d3")],
66 )
67
68 @testing.variation("criteria", ["rows", "norows", "emptyin"])
69 @testing.requires.update_returning
70 def test_update_returning(self, connection, criteria):
71 t = self.tables.plain_pk
72
73 stmt = t.update().returning(t.c.id, t.c.data)
74
75 if criteria.norows:
76 stmt = stmt.where(t.c.id == 10)
77 elif criteria.rows:
78 stmt = stmt.where(t.c.id == 2)
79 elif criteria.emptyin:
80 stmt = stmt.where(t.c.id.in_([]))
81 else:
82 criteria.fail()
83
84 r = connection.execute(stmt, dict(data="d2_new"))
85 assert not r.is_insert
86 assert r.returns_rows
87 eq_(r.keys(), ["id", "data"])
88
89 if criteria.rows:
90 eq_(r.all(), [(2, "d2_new")])
91 else:
92 eq_(r.all(), [])
93
94 eq_(
95 connection.execute(t.select().order_by(t.c.id)).fetchall(),
96 (
97 [(1, "d1"), (2, "d2_new"), (3, "d3")]
98 if criteria.rows
99 else [(1, "d1"), (2, "d2"), (3, "d3")]
100 ),
101 )
102
103 @testing.variation("criteria", ["rows", "norows", "emptyin"])
104 @testing.requires.delete_returning
105 def test_delete_returning(self, connection, criteria):
106 t = self.tables.plain_pk
107
108 stmt = t.delete().returning(t.c.id, t.c.data)
109
110 if criteria.norows:
111 stmt = stmt.where(t.c.id == 10)
112 elif criteria.rows:
113 stmt = stmt.where(t.c.id == 2)
114 elif criteria.emptyin:
115 stmt = stmt.where(t.c.id.in_([]))
116 else:
117 criteria.fail()
118
119 r = connection.execute(stmt)
120 assert not r.is_insert
121 assert r.returns_rows
122 eq_(r.keys(), ["id", "data"])
123
124 if criteria.rows:
125 eq_(r.all(), [(2, "d2")])
126 else:
127 eq_(r.all(), [])
128
129 eq_(
130 connection.execute(t.select().order_by(t.c.id)).fetchall(),
131 (
132 [(1, "d1"), (3, "d3")]
133 if criteria.rows
134 else [(1, "d1"), (2, "d2"), (3, "d3")]
135 ),
136 )
137
138
139__all__ = ("SimpleUpdateDeleteTest",)
140 