Skip to content

Commit a193971

Browse files
committed
normalize execute style for events, 2.0
The _execute_20 and exec_driver_sql methods should wrap up the parameters so that they represent the single list / single dictionary style of invocation into the legacy methods. then the before_ after_ execute event handlers should be receiving the parameter dictionary as a single dictionary. this requires that we break out distill_params to work differently if event handlers are present. additionally, add deprecation warnings for old argument passing styles. Change-Id: I97cb4d06adfcc6b889f10d01cc7775925cffb116
1 parent 0901190 commit a193971

12 files changed

Lines changed: 477 additions & 137 deletions

File tree

doc/build/core/tutorial.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ and use it in the "normal" way:
323323
.. sourcecode:: pycon+sql
324324

325325
>>> ins = users.insert()
326-
>>> conn.execute(ins, id=2, name='wendy', fullname='Wendy Williams')
326+
>>> conn.execute(ins, {"id": 2, "name":"wendy", "fullname": "Wendy Williams"})
327327
{opensql}INSERT INTO users (id, name, fullname) VALUES (?, ?, ?)
328328
[...] (2, 'wendy', 'Wendy Williams')
329329
COMMIT
@@ -972,7 +972,7 @@ unchanged. Below, we create a :func:`_expression.text` object and execute it:
972972
... "AND users.name BETWEEN :x AND :y "
973973
... "AND (addresses.email_address LIKE :e1 "
974974
... "OR addresses.email_address LIKE :e2)")
975-
>>> conn.execute(s, x='m', y='z', e1='%@aol.com', e2='%@msn.com').fetchall()
975+
>>> conn.execute(s, {"x":"m", "y":"z", "e1":"%@aol.com", "e2":"%@msn.com"}).fetchall()
976976
{opensql}SELECT users.fullname || ', ' || addresses.email_address AS title
977977
FROM users, addresses
978978
WHERE users.id = addresses.user_id AND users.name BETWEEN ? AND ? AND
@@ -1127,7 +1127,7 @@ need to refer to any pre-established :class:`_schema.Table` metadata:
11271127
... "OR addresses.email_address LIKE :y)")
11281128
... )
11291129
... ).select_from(text('users, addresses'))
1130-
>>> conn.execute(s, x='%@aol.com', y='%@msn.com').fetchall()
1130+
>>> conn.execute(s, {"x": "%@aol.com", "y": "%@msn.com"}).fetchall()
11311131
{opensql}SELECT users.fullname || ', ' || addresses.email_address AS title
11321132
FROM users, addresses
11331133
WHERE users.id = addresses.user_id AND users.name BETWEEN 'm' AND 'z'
@@ -1180,7 +1180,7 @@ be quoted:
11801180
... )
11811181
... ).select_from(table('users')).select_from(table('addresses'))
11821182

1183-
>>> conn.execute(s, x='%@aol.com', y='%@msn.com').fetchall()
1183+
>>> conn.execute(s, {"x":"%@aol.com", "y":"%@msn.com"}).fetchall()
11841184
{opensql}SELECT users.fullname || ? || addresses.email_address AS anon_1
11851185
FROM users, addresses
11861186
WHERE users.id = addresses.user_id

lib/sqlalchemy/cextension/utils.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ distill_params(PyObject *self, PyObject *args)
2626
// TODO: pass the Connection in so that there can be a standard
2727
// method for warning on parameter format
2828

29-
PyObject *multiparams, *params;
29+
PyObject *connection, *multiparams, *params;
3030
PyObject *enclosing_list, *double_enclosing_list;
3131
PyObject *zero_element, *zero_element_item;
32+
PyObject *tmp;
3233
Py_ssize_t multiparam_size, zero_element_length;
3334

34-
if (!PyArg_UnpackTuple(args, "_distill_params", 2, 2, &multiparams, &params)) {
35+
if (!PyArg_UnpackTuple(args, "_distill_params", 3, 3, &connection, &multiparams, &params)) {
3536
return NULL;
3637
}
3738

@@ -47,8 +48,12 @@ distill_params(PyObject *self, PyObject *args)
4748

4849
if (multiparam_size == 0) {
4950
if (params != Py_None && PyMapping_Size(params) != 0) {
50-
// TODO: this is keyword parameters, emit parameter format
51-
// deprecation warning
51+
52+
tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
53+
if (tmp == NULL) {
54+
return NULL;
55+
}
56+
5257
enclosing_list = PyList_New(1);
5358
if (enclosing_list == NULL) {
5459
return NULL;
@@ -102,6 +107,7 @@ distill_params(PyObject *self, PyObject *args)
102107
* execute(stmt, ("value", "value"))
103108
*/
104109
Py_XDECREF(zero_element_item);
110+
105111
enclosing_list = PyList_New(1);
106112
if (enclosing_list == NULL) {
107113
return NULL;
@@ -131,6 +137,11 @@ distill_params(PyObject *self, PyObject *args)
131137
}
132138
return enclosing_list;
133139
} else {
140+
tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
141+
if (tmp == NULL) {
142+
return NULL;
143+
}
144+
134145
enclosing_list = PyList_New(1);
135146
if (enclosing_list == NULL) {
136147
return NULL;
@@ -157,8 +168,12 @@ distill_params(PyObject *self, PyObject *args)
157168
}
158169
}
159170
else {
160-
// TODO: this is multiple positional params, emit parameter format
161-
// deprecation warning
171+
172+
tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
173+
if (tmp == NULL) {
174+
return NULL;
175+
}
176+
162177
zero_element = PyTuple_GetItem(multiparams, 0);
163178
if (PyObject_HasAttrString(zero_element, "__iter__") &&
164179
!PyObject_HasAttrString(zero_element, "strip")

lib/sqlalchemy/dialects/postgresql/base.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,7 +2855,11 @@ def get_table_names(self, connection, schema=None, **kw):
28552855
"JOIN pg_namespace n ON n.oid = c.relnamespace "
28562856
"WHERE n.nspname = :schema AND c.relkind in ('r', 'p')"
28572857
).columns(relname=sqltypes.Unicode),
2858-
schema=schema if schema is not None else self.default_schema_name,
2858+
dict(
2859+
schema=schema
2860+
if schema is not None
2861+
else self.default_schema_name
2862+
),
28592863
)
28602864
return [name for name, in result]
28612865

@@ -2970,7 +2974,7 @@ def get_columns(self, connection, table_name, schema=None, **kw):
29702974
.bindparams(sql.bindparam("table_oid", type_=sqltypes.Integer))
29712975
.columns(attname=sqltypes.Unicode, default=sqltypes.Unicode)
29722976
)
2973-
c = connection.execute(s, table_oid=table_oid)
2977+
c = connection.execute(s, dict(table_oid=table_oid))
29742978
rows = c.fetchall()
29752979

29762980
# dictionary with (name, ) if default search path or (schema, name)
@@ -3212,7 +3216,7 @@ def get_pk_constraint(self, connection, table_name, schema=None, **kw):
32123216
ORDER BY k.ord
32133217
"""
32143218
t = sql.text(PK_SQL).columns(attname=sqltypes.Unicode)
3215-
c = connection.execute(t, table_oid=table_oid)
3219+
c = connection.execute(t, dict(table_oid=table_oid))
32163220
cols = [r[0] for r in c.fetchall()]
32173221

32183222
PK_CONS_SQL = """
@@ -3222,7 +3226,7 @@ def get_pk_constraint(self, connection, table_name, schema=None, **kw):
32223226
ORDER BY 1
32233227
"""
32243228
t = sql.text(PK_CONS_SQL).columns(conname=sqltypes.Unicode)
3225-
c = connection.execute(t, table_oid=table_oid)
3229+
c = connection.execute(t, dict(table_oid=table_oid))
32263230
name = c.scalar()
32273231

32283232
return {"constrained_columns": cols, "name": name}
@@ -3270,7 +3274,7 @@ def get_foreign_keys(
32703274
t = sql.text(FK_SQL).columns(
32713275
conname=sqltypes.Unicode, condef=sqltypes.Unicode
32723276
)
3273-
c = connection.execute(t, table=table_oid)
3277+
c = connection.execute(t, dict(table=table_oid))
32743278
fkeys = []
32753279
for conname, condef, conschema in c.fetchall():
32763280
m = re.search(FK_REGEX, condef).groups()
@@ -3442,7 +3446,7 @@ def get_indexes(self, connection, table_name, schema, **kw):
34423446
t = sql.text(IDX_SQL).columns(
34433447
relname=sqltypes.Unicode, attname=sqltypes.Unicode
34443448
)
3445-
c = connection.execute(t, table_oid=table_oid)
3449+
c = connection.execute(t, dict(table_oid=table_oid))
34463450

34473451
indexes = defaultdict(lambda: defaultdict(dict))
34483452

@@ -3584,7 +3588,7 @@ def get_unique_constraints(
35843588
"""
35853589

35863590
t = sql.text(UNIQUE_SQL).columns(col_name=sqltypes.Unicode)
3587-
c = connection.execute(t, table_oid=table_oid)
3591+
c = connection.execute(t, dict(table_oid=table_oid))
35883592

35893593
uniques = defaultdict(lambda: defaultdict(dict))
35903594
for row in c.fetchall():
@@ -3635,7 +3639,7 @@ def get_check_constraints(self, connection, table_name, schema=None, **kw):
36353639
cons.contype = 'c'
36363640
"""
36373641

3638-
c = connection.execute(sql.text(CHECK_SQL), table_oid=table_oid)
3642+
c = connection.execute(sql.text(CHECK_SQL), dict(table_oid=table_oid))
36393643

36403644
ret = []
36413645
for name, src in c:

0 commit comments

Comments
 (0)