summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-09-08 21:34:39 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2017-09-08 21:41:13 -0400
commit70be7312f10a2241cde3e6472af15ef5a9ae222a (patch)
tree7e7e28baf1a5fc7d2d07c6249b2b177abe770ef8
parent5ae984b946f87cc485c29c4c947a8649d4c4c422 (diff)
downloadsqlalchemy-70be7312f10a2241cde3e6472af15ef5a9ae222a.tar.gz
Rename MySQL dml.insert().values to .inserted
Changed the name of the ``.values`` attribute of the new MySQL INSERT..ON DUPLICATE KEY UPDATE construct to ``.inserted``, as :class:`.Insert` already has a method called :meth:`.Insert.values`. The ``.inserted`` attribute ultimately renders the MySQL ``VALUES()`` function. Change-Id: I8da8e30a3077698385a4b77e2c2032e2d1ff10b2 Fixes: #4072
-rw-r--r--doc/build/changelog/migration_12.rst2
-rw-r--r--doc/build/changelog/unreleased_12/4072.rst9
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py14
-rw-r--r--lib/sqlalchemy/dialects/mysql/dml.py23
-rw-r--r--test/dialect/mysql/test_compiler.py14
-rw-r--r--test/dialect/mysql/test_on_duplicate.py13
6 files changed, 43 insertions, 32 deletions
diff --git a/doc/build/changelog/migration_12.rst b/doc/build/changelog/migration_12.rst
index 4cfaf38c4..87c08dc21 100644
--- a/doc/build/changelog/migration_12.rst
+++ b/doc/build/changelog/migration_12.rst
@@ -1336,7 +1336,7 @@ This :class:`~.expression.Insert` subclass adds a new method
values(id='some_id', data='some data to insert')
on_conflict_stmt = insert_stmt.on_duplicate_key_update(
- data=stmt.values.data,
+ data=stmt.inserted.data,
status='U'
)
diff --git a/doc/build/changelog/unreleased_12/4072.rst b/doc/build/changelog/unreleased_12/4072.rst
new file mode 100644
index 000000000..3e5e83f24
--- /dev/null
+++ b/doc/build/changelog/unreleased_12/4072.rst
@@ -0,0 +1,9 @@
+.. change::
+ :tags: bug, mysql
+ :tickets: 4072
+
+ Changed the name of the ``.values`` attribute of the new MySQL
+ INSERT..ON DUPLICATE KEY UPDATE construct to ``.inserted``, as
+ :class:`.Insert` already has a method called :meth:`.Insert.values`.
+ The ``.inserted`` attribute ultimately renders the MySQL ``VALUES()``
+ function. \ No newline at end of file
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 976ff367b..b1b249001 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -332,8 +332,8 @@ INSERT...ON DUPLICATE KEY UPDATE (Upsert)
MySQL allows "upserts" (update or insert)
of rows into a table via the ``ON DUPLICATE KEY UPDATE`` clause of the
``INSERT`` statement. A candidate row will only be inserted if that row does
-not match an existing primary or unique key in the table; otherwise, an UPDATE will
-be performed. The statement allows for separate specification of the
+not match an existing primary or unique key in the table; otherwise, an UPDATE
+will be performed. The statement allows for separate specification of the
values to INSERT versus the values for UPDATE.
SQLAlchemy provides ``ON DUPLICATE KEY UPDATE`` support via the MySQL-specific
@@ -347,7 +347,7 @@ the generative method :meth:`~.mysql.dml.Insert.on_duplicate_key_update`::
data='inserted value')
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
- data=insert_stmt.values.data,
+ data=insert_stmt.inserted.data,
status='U'
)
@@ -381,7 +381,7 @@ as values::
unless they are manually specified explicitly in the parameters.
In order to refer to the proposed insertion row, the special alias
-:attr:`~.mysql.dml.Insert.values` is available as an attribute on
+:attr:`~.mysql.dml.Insert.inserted` is available as an attribute on
the :class:`.mysql.dml.Insert` object; this object is a
:class:`.ColumnCollection` which contains all columns of the target
table::
@@ -394,11 +394,11 @@ table::
author='jlh')
do_update_stmt = stmt.on_duplicate_key_update(
data="updated value",
- author=stmt.values.author
+ author=stmt.inserted.author
)
conn.execute(do_update_stmt)
-When rendered, the "values" namespace will produce the expression
+When rendered, the "inserted" namespace will produce the expression
``VALUES(<columnname>)``.
.. versionadded:: 1.2 Added support for MySQL ON DUPLICATE KEY UPDATE clause
@@ -921,7 +921,7 @@ class MySQLCompiler(compiler.SQLCompiler):
val.type = column.type
value_text = self.process(val.self_group(), use_schema=False)
elif isinstance(val, elements.ColumnClause) \
- and val.table is on_duplicate.values_alias:
+ and val.table is on_duplicate.inserted_alias:
value_text = 'VALUES(' + self.preparer.quote(column.name) + ')'
else:
value_text = self.process(val.self_group(), use_schema=False)
diff --git a/lib/sqlalchemy/dialects/mysql/dml.py b/lib/sqlalchemy/dialects/mysql/dml.py
index 743510317..217dc7a2a 100644
--- a/lib/sqlalchemy/dialects/mysql/dml.py
+++ b/lib/sqlalchemy/dialects/mysql/dml.py
@@ -18,26 +18,27 @@ class Insert(StandardInsert):
"""
@property
- def values(self):
- """Provide the ``values`` namespace for an ON DUPLICATE KEY UPDATE statement
+ def inserted(self):
+ """Provide the "inserted" namespace for an ON DUPLICATE KEY UPDATE statement
MySQL's ON DUPLICATE KEY UPDATE clause allows reference to the row
that would be inserted, via a special function called ``VALUES()``.
This attribute provides all columns in this row to be referenaceable
such that they will render within a ``VALUES()`` function inside the
- ON DUPLICATE KEY UPDATE clause.
+ ON DUPLICATE KEY UPDATE clause. The attribute is named ``.inserted``
+ so as not to conflict with the existing :meth:`.Insert.values` method.
.. seealso::
:ref:`mysql_insert_on_duplicate_key_update` - example of how
- to use :attr:`.Insert.values`
+ to use :attr:`.Insert.inserted`
"""
- return self.values_alias.columns
+ return self.inserted_alias.columns
@util.memoized_property
- def values_alias(self):
- return alias(self.table, name='values')
+ def inserted_alias(self):
+ return alias(self.table, name='inserted')
@_generative
def on_duplicate_key_update(self, **kw):
@@ -61,8 +62,8 @@ class Insert(StandardInsert):
:ref:`mysql_insert_on_duplicate_key_update`
"""
- values_alias = getattr(self, 'values_alias', None)
- self._post_values_clause = OnDuplicateClause(values_alias, kw)
+ inserted_alias = getattr(self, 'inserted_alias', None)
+ self._post_values_clause = OnDuplicateClause(inserted_alias, kw)
return self
@@ -72,8 +73,8 @@ insert = public_factory(Insert, '.dialects.mysql.insert')
class OnDuplicateClause(ClauseElement):
__visit_name__ = 'on_duplicate_key_update'
- def __init__(self, values_alias, update):
- self.values_alias = values_alias
+ def __init__(self, inserted_alias, update):
+ self.inserted_alias = inserted_alias
if not update or not isinstance(update, dict):
raise ValueError('update parameter must be a non-empty dictionary')
self.update = update
diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py
index 3663a4800..e8731e532 100644
--- a/test/dialect/mysql/test_compiler.py
+++ b/test/dialect/mysql/test_compiler.py
@@ -704,10 +704,10 @@ class InsertOnDuplicateTest(fixtures.TestBase, AssertsCompiledSQL):
)
def test_from_values(self):
- stmt = insert(
- self.table, [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
+ stmt = insert(self.table).values(
+ [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
stmt = stmt.on_duplicate_key_update(
- bar=stmt.values.bar, baz=stmt.values.baz)
+ bar=stmt.inserted.bar, baz=stmt.inserted.baz)
expected_sql = (
'INSERT INTO foos (id, bar) VALUES (%s, %s), (%s, %s) '
'ON DUPLICATE KEY UPDATE bar = VALUES(bar), baz = VALUES(baz)'
@@ -715,8 +715,8 @@ class InsertOnDuplicateTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(stmt, expected_sql)
def test_from_literal(self):
- stmt = insert(
- self.table, [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
+ stmt = insert(self.table).values(
+ [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
stmt = stmt.on_duplicate_key_update(bar=literal_column('bb'))
expected_sql = (
'INSERT INTO foos (id, bar) VALUES (%s, %s), (%s, %s) '
@@ -725,8 +725,8 @@ class InsertOnDuplicateTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(stmt, expected_sql)
def test_python_values(self):
- stmt = insert(
- self.table, [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
+ stmt = insert(self.table).values(
+ [{'id': 1, 'bar': 'ab'}, {'id': 2, 'bar': 'b'}])
stmt = stmt.on_duplicate_key_update(bar="foobar")
expected_sql = (
'INSERT INTO foos (id, bar) VALUES (%s, %s), (%s, %s) '
diff --git a/test/dialect/mysql/test_on_duplicate.py b/test/dialect/mysql/test_on_duplicate.py
index 2ff4a58cc..9a026f9ed 100644
--- a/test/dialect/mysql/test_on_duplicate.py
+++ b/test/dialect/mysql/test_on_duplicate.py
@@ -29,8 +29,9 @@ class OnDuplicateTest(fixtures.TablesTest):
foos = self.tables.foos
with testing.db.connect() as conn:
conn.execute(insert(foos, dict(id=1, bar='b', baz='bz')))
- stmt = insert(foos, [dict(id=1, bar='ab'), dict(id=2, bar='b')])
- stmt = stmt.on_duplicate_key_update(bar=stmt.values.bar)
+ stmt = insert(foos).values(
+ [dict(id=1, bar='ab'), dict(id=2, bar='b')])
+ stmt = stmt.on_duplicate_key_update(bar=stmt.inserted.bar)
result = conn.execute(stmt)
eq_(result.inserted_primary_key, [2])
eq_(
@@ -41,17 +42,17 @@ class OnDuplicateTest(fixtures.TablesTest):
def test_last_inserted_id(self):
foos = self.tables.foos
with testing.db.connect() as conn:
- stmt = insert(foos, {"bar": "b", "baz": "bz"})
+ stmt = insert(foos).values({"bar": "b", "baz": "bz"})
result = conn.execute(
stmt.on_duplicate_key_update(
- bar=stmt.values.bar, baz="newbz")
+ bar=stmt.inserted.bar, baz="newbz")
)
eq_(result.inserted_primary_key, [1])
- stmt = insert(foos, {"id": 1, "bar": "b", "baz": "bz"})
+ stmt = insert(foos).values({"id": 1, "bar": "b", "baz": "bz"})
result = conn.execute(
stmt.on_duplicate_key_update(
- bar=stmt.values.bar, baz="newbz")
+ bar=stmt.inserted.bar, baz="newbz")
)
eq_(result.inserted_primary_key, [1])