Cool, wasn't aware of that feature! Thanks!

On Fri, Jun 14, 2019 at 5:50 PM Mike Bayer <mike...@zzzcomputing.com> wrote:

>
>
> On Fri, Jun 14, 2019, at 12:46 PM, Mike Bayer wrote:
>
>
>
> On Fri, Jun 14, 2019, at 12:22 PM, João Miguel Neves wrote:
>
> Not performance, actually to avoid a race condition with key/values
> written to JSONB fields. Ended up with the following function that we use
> for when multiple updates at the same time can occur (from the frontend
> mostly). It's based on your recommendations from
> https://groups.google.com/forum/#!topic/sqlalchemy/hjjIyEC8KHQ
>
> When we got 2 requests in parallel (one updating key1 with value1 and
> another updating key2 with value2), the first would write value1, but as
> the second had loaded the JSONB field before, it would write to key2 and
> then save the whole content of the JSONB field without the update to key1
> effectively losing data in our case.
>
> def atomic_jsonb_set(context, dynamic_column_name, column_id, value):
>     id_key = [col.name for col in inspect(context.__class__).primary_key]
>     identifier = {key: getattr(context, key) for key in id_key}
>
>     DBSession.query(context.__class__).filter_by(**identifier).update(
>         {
>             dynamic_column_name: func.jsonb_set(
>                 getattr(context.__class__, dynamic_column_name),
>                 f"{{{column_id}}}",
>                 config["sqlalchemy.json_serializer"](value),
>             )
>         },
>         synchronize_session="fetch",
>     )
>
>
>
> OK so the patterns you can use with that are the versioning column, or if
> you want the UPDATE to be atomic there might be complications if you are
> updating columns in both "person" and "engineer".    I might use
> SELECT..FOR UPDATE for a pessimistic approach.
>
>
> oh and by versioning column i mean
> https://docs.sqlalchemy.org/en/13/orm/versioning.html?highlight=versioning,
> <https://docs.sqlalchemy.org/en/13/orm/versioning.html?highlight=versioning>
> which is also using regular Session.add() types of patterns, not
> query.update().
>
>
>
>
>
>
> On Fri, Jun 14, 2019 at 5:07 PM Mike Bayer <mike...@zzzcomputing.com>
> wrote:
>
>
>
>
> On Fri, Jun 14, 2019, at 11:49 AM, João Miguel Neves wrote:
>
> Hi Mike,
>
> Thank you very much for the quick response!
>
> Is there any other way to find the right table from the model other than
> somthing like Engineer.name.property.columns[0].table? (I'm trying to do an
> update in a codepath that can have several different models passed to it)
>
>
>
> you're doing query.update() for performance reasons, right?  yeah you
> probably have to do something like that, or just use regular session
> patterns to update data.
>
>
>
>
> TIA,
> João
>
> On Fri, Jun 14, 2019 at 4:04 PM Mike Bayer <mike...@zzzcomputing.com>
> wrote:
>
>
>
>
> On Fri, Jun 14, 2019, at 10:30 AM, João Miguel Neves wrote:
>
> Hi,
>
> I have a situation where an update tries to update the wrong table on when
> a column comes from the parent table and is not on the current table. I'll
> grant I didn't quite understand all the caveats in
> https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.update
> so let me apologise if it's written there - then I just need a pointer in
> the right direction. Here is some sample code (mostly adapted from
> https://stackoverflow.com/questions/44183500/problems-with-update-and-table-inheritance-with-sqlalchemy
> - the code won't work on sqlite).
>
>
>
> Hi there -
>
> yes the caveats refer to the joined inheritance situation as where there
> are intricacies here.
>
> Your UPDATE statement refers to the "name" column which is part of People,
> so you need to format your UPDATE statement in terms of the "people" table,
> which means the second query is not supported.   It at least has to be
> against "People" otherwise the UPDATE is only targeting the "engineer"
> table.
>
> if you want to limit the "name" updates to only those rows that are
> Engineer, use the discriminator column to filter to People.type ==
> "engineer".
>
>
>
>
> zi
> ----
>
> The error message is:
>
> Traceback (most recent call last):
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 1244, in _execute_context
>     cursor, statement, parameters, context
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/default.py",
> line 550, in do_execute
>     cursor.execute(statement, parameters)
> psycopg2.errors.UndefinedColumn: column "name" of relation "engineer" does
> not exist
> LINE 1: UPDATE engineer SET name='Mary', updated=now() FROM people W...
>                             ^
>
>
> The above exception was the direct cause of the following exception:
>
> Traceback (most recent call last):
>   File "update-inheritance.py", line 63, in <module>
>     Engineer.name == 'James', ).update({Engineer.name: 'Mary'})
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/orm/query.py",
> line 3824, in update
>     update_op.exec_()
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py",
> line 1673, in exec_
>     self._do_exec()
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py",
> line 1866, in _do_exec
>     self._execute_stmt(update_stmt)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py",
> line 1678, in _execute_stmt
>     self.result = self.query._execute_crud(stmt, self.mapper)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/orm/query.py",
> line 3356, in _execute_crud
>     return conn.execute(stmt, self._params)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 988, in execute
>     return meth(self, multiparams, params)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/sql/elements.py",
> line 287, in _execute_on_connection
>     return connection._execute_clauseelement(self, multiparams, params)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 1107, in _execute_clauseelement
>     distilled_params,
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 1248, in _execute_context
>     e, statement, parameters, cursor, context
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 1466, in _handle_dbapi_exception
>     util.raise_from_cause(sqlalchemy_exception, exc_info)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/util/compat.py",
> line 383, in raise_from_cause
>     reraise(type(exception), exception, tb=exc_tb, cause=cause)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/util/compat.py",
> line 128, in reraise
>     raise value.with_traceback(tb)
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/base.py",
> line 1244, in _execute_context
>     cursor, statement, parameters, context
>   File
> "/home/joao/testes/sa-bugs/.ve/lib/python3.6/site-packages/sqlalchemy/engine/default.py",
> line 550, in do_execute
>     cursor.execute(statement, parameters)
> sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedColumn) column
> "name" of relation "engineer" does not exist
> LINE 1: UPDATE engineer SET name='Mary', updated=now() FROM people W...
>                             ^
>
> [SQL: UPDATE engineer SET name=%(people_name)s, updated=now() FROM people
> WHERE engineer.id = people.id AND people.name = %(name_1)s]
> [parameters: {'people_name': 'Mary', 'name_1': 'James'}]
> (Background on this error at: http://sqlalche.me/e/f405)
> I can get the correct table to update through:
>
> table = Engineer.name.property.columns[0].table
>
> And the following update works (albeit with a slightly different
> semantics):
>
> update(table).where(table.c.name == 'James').values({table.c.name :
> 'Mary'})
> From what I've read, adding the People.id == Engineer.id should be enough,
> but it seems like I missed some detail. Can you help?
>
> Thanks in advance for any help/pointers,
> João
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/4b8377e7-3fff-4750-aebf-aaa5eaac35da%40googlegroups.com
> <https://groups.google.com/d/msgid/sqlalchemy/4b8377e7-3fff-4750-aebf-aaa5eaac35da%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/085a157e-cda0-478a-b4a8-04903d69b780%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/085a157e-cda0-478a-b4a8-04903d69b780%40www.fastmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/CAJGrhWYeQFCpOiwbtToqnVTq8qy%2Bya3V7NUmmotY7%2Ber-0xYvg%40mail.gmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/CAJGrhWYeQFCpOiwbtToqnVTq8qy%2Bya3V7NUmmotY7%2Ber-0xYvg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/27f24134-661e-4c16-982a-6983a82609a4%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/27f24134-661e-4c16-982a-6983a82609a4%40www.fastmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/CAJGrhWZ_REpV09w5YVz-oY4BoTQjuB2DqTUirwwd8sAweKuHMg%40mail.gmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/CAJGrhWZ_REpV09w5YVz-oY4BoTQjuB2DqTUirwwd8sAweKuHMg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/b743f771-12db-4635-bc2e-5d44ec140ac5%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/b743f771-12db-4635-bc2e-5d44ec140ac5%40www.fastmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/0a138c5b-992a-4410-876b-32351a57d2fb%40www.fastmail.com
> <https://groups.google.com/d/msgid/sqlalchemy/0a138c5b-992a-4410-876b-32351a57d2fb%40www.fastmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/CAJGrhWbmMb1PPyLSkp7AjDDFkZmEnPG%2BejmLoui_urtzZKOhrw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to