Hi Shane – solved! I had been using SQLiteLib2’s “query” command, but it turns out that’s not the way to do it.
I was looking through your documentation again to see if I was missing something, and it occurred to me that a command like “ATTACH”, while not a command that writes or updates anything to the database itself, is more of a precursor to a “query” rather than a query itself. I work pretty exclusively with read-only databases, trying to use AppleScript to peer over the shoulder of another program that’s doing the writing to the database.
It turns out that the way to use ATTACH is with either “update” (if you’re attaching one database) or “execute statements on dB” if you need to attach several, with each ATTACH statement separated by a semicolon. E.g.:
property db2023 : “/path/to/database2023.sqlite”
property db2022 : “/path/to/database2022.sqlite”
property db2021 : “/path/to/database2021.sqlite”
set theDb to open db in file db2023
set theStatements to (execute statements on db theDb sql string “ATTACH DATABASE '” & db2021 & “’ AS db2021; ATTACH DATABASE '” & db2022 & “’ AS db2022”)
Once you’ve done that, you can then construct a query that spans all three databases. In my case, pulling race timing data from 3 separate databases associated with 3 separate events. E.g:
set theQuery to (query db theDb sql string “SELECT Levels.Level, ROUND(AVG(FinishTime), 4) AS AverageFinishTime FROM (SELECT LevelID, FinishTime FROM db2021.bigChart UNION ALL SELECT LevelID, FinishTime FROM db2022.bigChart UNION ALL SELECT LevelID, FinishTime FROM bigChart) AS CombinedData JOIN Levels ON CombinedData.LevelID = Levels.LevelID WHERE Levels.LevelID != 9 GROUP BY Levels.Level ORDER BY AverageFinishTime ASC;”)
Now, I don’t know if this is a SQLite quirk that the correct command to use an ATTACH statement is “update” or “execute transaction”, but I would note that the ATTACH statement APPEARS to be “non destructive,” in the sense that even though we’re supposedly writing to the database (“update” implies you’re modifying the database to new values), using SQLiteLib this way does NOT seem to actually write to the database file on disk. In my case, that’s a good thing, since in my use case, I am trying very hard not to interfere with the behavior of the program that’s actually writing to the database.
Glad to have this extra feature available to me, and I hope others can use it, too! And Shane, thanks for a great little tool. Being able to work so efficiently with SQLite in AppleScript has been an absolute game changer for the kinds of data analysis I enjoy doing!
M2