Rationale:
We use an in-memory sqlite database for quota tests. With SA 2.0 (or
with the `future` flag enabled on the engine), the following conflict
happens: (this is a simplified model)
foo = Foo()
session.add(foo)
session.flush()
engine = session.get_bind()
with engine.connect() as conn:
conn.execute(some-sql)
foo.bar = "new value"
session.commit() # BOOM!!!! sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'galaxy_user' expected to update 1 row(s); 0 were matched.
Reason for BOOM:
With an in-memory database, the underlying dbapi_connection object is
the same for the session and the engine.connect(). Here's what happens:
line 10: foo is flushed to the db tmp buffer
line 14: conn is closed on exit from context manager, which issues a
rollback, which rolls back whatever is in the tmp buffer - so foo is
never inserted.
line 16: foo is updated
line 17: error happens: the session thinks it's updating foo's record in
the db, but that record does not exist therefore, "0 rows matched".
Solution: commit instead of flushing - then foo is inserted.
1. Upgrade Query to Select
2. Factor out query-building logic. The previous version returned tuples
of items OR models (ORM objects), depending on the calling code
(several similar data access methods were combined into this one
generic method in PR #12056). The Query object would "magically"
convert tuples of ORM objects to ORM objects. The new unified Select
object does not do that. As as result, with Select, this method would
return tuples of items or tuples of models (not models):
result1 = session.execute(statement2)
result1 == [("element_identifier_0", "element_identifier_1", "extension", "state"), ...]
result2 = session.execute(statement2)
result2 == [(dataset1,), (dataset2,) ...]
Factoring out the query-building logic and having the caller execute
it depending on the expected data structure solves this.
Fixed by running:
```
ack --type=python -f | grep -v '^lib/galaxy/schema/bco/\|^lib/galaxy/schema/drs/\|^tools/\|^.venv/\|^.tox/' | grep -v '^lib/galaxy/files/sources/\|^lib/galaxy/job_metrics/\|^lib/galaxy/objectstore/\|^lib/galaxy/tool_util/\|^lib/galaxy/util/' | xargs auto-walrus
make format
```
Note that the directories for the packages listed in
`packages/packages_for_pulsar_by_dep_dag.txt`
were explictly excluded.
This commit creates two new packages - below a description of these packages and why they are being created.
galaxy-schema: This package contains the pydantic models that power the API. The purpose of packaging them is to ensure they can be reused by clients with minimal external dependencies. Reusing the schema in client code would very quickly provide rapid documentation and validation and static checking for Python clients using the Galaxy API.
galaxy-tool-shed: This package contains the tool shed server code. This has been a long term project to allow the tool shed to be spun out but maintain real galaxy dependencies and maintain testing. More discussions around this project can be found as part of https://github.com/galaxyproject/galaxy/pull/8830.
In galaxy, HistoryAudit.prune() executes in the context of a separate thread, where it
starts and commits a new transaction, closing a scoped session on exit. Thus, here we
should end the current transaction (via rollback) and add the History objects to a new
session, as the previous one will be closed.
I guess there's a chance downstream users may run into version conflicts
if we pin ro-cate to 0.7.0, and we also don't really want to bump stable
version dependencies.
It would just give you an extra line with the correct offset so there is no way this would ever be detected as a UI bug - but I have some unit tests to verify the correctness.