Skip to content

[AI-generated, unverified] SQLAlchemy 2.1, rdflib 7 graph-aware store, publish as ifcopenshell-rdflib-sqlalchemy - #1

Merged
Moult merged 6 commits into
developfrom
fix/sqlalchemy-2.1
Sep 24, 2026
Merged

Moult merged 6 commits into
developfrom
fix/sqlalchemy-2.1

Conversation

@Moult

@Moult Moult commented Sep 24, 2026

Copy link
Copy Markdown

(AI-written, not verified by Dion.)

Brings this fork from upstream develop to something Bonsai can install today:

  1. Andrej's pkg_resources → importlib.metadata change (upstream Fix for deprecated/removed pkg_resources package RDFLib/rdflib-sqlalchemy#116, unmerged), without which the package does not import on Python 3.12+.
  2. .subquery() on the count query: SQLAlchemy 2.1.0 (2026-09-24) removed the implicit Select-to-FROM coercion and len(graph) raised ArgumentError on every store (upstream Count subqueries explicitly: SQLAlchemy 2.1 no longer coerces a Select into a FROM RDFLib/rdflib-sqlalchemy#117).
  3. The where-clause guards and bind(override=) from Gabe Fierro's brickschema-rdflib-sqlalchemy fork, so removals without a constraint work under SQLAlchemy 2.
  4. A graph-aware store (a table of named graphs, add_graph(), remove_graph(), contexts() unioning both sources): rdflib 7's Dataset, which its N3 parser and ConjunctiveGraph now build, refuses a store that is not, which failed three of the package's own tests.
  5. The rename to ifcopenshell-rdflib-sqlalchemy 0.7.0, README, and a CI matrix on Python 3.9–3.13 × SQLAlchemy 2.0/2.1.

With DB=sqlite, the suite passes under both SQLAlchemy lines (45 passed); the built wheel installs in a fresh venv with SQLAlchemy 2.1.0 and registers the SQLAlchemy rdflib store plugin. Not run: the MySQL and PostgreSQL jobs (CI has them).

🤖 Generated with Claude Code

https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL

Andrej730 and others added 5 commits September 25, 2026 08:37
…t into a FROM

union_select() built the count query for __len__() by passing the inner
select() straight to select_from(). SQLAlchemy 1.4 and 2.0 wrapped it in
a subquery with a deprecation warning ("Implicit coercion of SELECT and
textual SELECT constructs into FROM clauses is deprecated; please call
.subquery()"); 2.1 removed the coercion and raises ArgumentError, so
len(graph) fails on every store. Calling .subquery() emits the same SQL
(SELECT count(*) AS aCount FROM (SELECT DISTINCT ...) AS anon_1 UNION
ALL ...) under both versions and silences the warning on 2.0.

This commit was written by an AI coding tool and has not been verified by
a human.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL
…rride

Taken from gtfierro/rdflib-sqlalchemy, the fork published on PyPI as
brickschema-rdflib-sqlalchemy (Gabe Fierro, 2024): build_clause()
returns None when a lookup or removal has no constraint, and SQLAlchemy
2 rejects where(None), so the full-triple and rdf:type selects in
union_select() and the four deletes in remove() only add the clause
when there is one. Store.bind() gains the override parameter rdflib 7
passes.

This commit was written by an AI coding tool and has not been verified by
a human.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL
…remove_graph()

rdflib 7 builds a Dataset for anything with named graphs, the N3 parser
included, and a Dataset refuses a store that is not graph-aware; with
this store that raised "Dataset must be backed by a graph-aware store!"
from parse() and from ConjunctiveGraph(), and failed three of the
package's own tests. A graph-aware store lists a graph that was added
while it is still empty and forgets it on remove_graph(); the statement
tables only know a context once a triple is in it, so the store gains a
{interned_id}_contexts table of the named graphs it was told about.
add_graph() records a graph once, remove_graph() removes its triples
and the record, contexts() with no triple unions the recorded graphs
with those the statements mention. Existing databases get the table on
the next open(create=True), as metadata.create_all() only adds what is
missing. The new test checks an empty graph is listed once, and that
remove_graph() takes a graph and its triples out.

This commit was written by an AI coding tool and has not been verified by
a human.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL
…both SQLAlchemy lines

IfcOpenShell's fork of RDFLib/rdflib-sqlalchemy: the distribution is
ifcopenshell-rdflib-sqlalchemy 0.7.0, the module and the rdflib store
plugin keep their names, so it replaces rdflib-sqlalchemy and
brickschema-rdflib-sqlalchemy in place; it is installed from this
repository's tags, not from PyPI. The README says what the fork carries
and points at the upstream PRs. The workflow tests Python 3.9 to 3.13
against SQLAlchemy 2.0 and 2.1 (2.1 needs 3.11, so those cells are
excluded), on current checkout and setup-python actions, without
fail-fast; tox's env mapping follows, and its "setup.py clean" step
goes, as virtualenvs on 3.12+ no longer carry setuptools. The PyPI
deploy job and its script go.

This commit was written by an AI coding tool and has not been verified by
a human.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wcN7XquTfUi4vsKQ4KchL
@Moult
Moult force-pushed the fix/sqlalchemy-2.1 branch from 1b55e68 to 1471548 Compare September 24, 2026 23:01
@Moult
Moult merged commit 1721eb9 into develop Sep 24, 2026
24 checks passed
@Moult
Moult deleted the fix/sqlalchemy-2.1 branch September 24, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants