Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

db: fix SQL TRANSACTION syntax compatible with all DB backends #3636

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

tmszi
Copy link
Member

@tmszi tmszi commented Apr 21, 2024

SQL TRANSACTION syntax (compatible with all DB backends):

BEGIN;
...;
COMMIT;

This default SQL TRANSACTION syntax is not compatible with MySQL/MariaDB DB backend:

BEGIN TRANSACTION;
...;
END TRANSACTION;

Successfully tested with SQLite, PostgreSQL, MySQL DB backend.

@tmszi tmszi added this to the 8.4.0 milestone Apr 21, 2024
@tmszi tmszi self-assigned this Apr 21, 2024
@github-actions github-actions bot added vector Related to vector data processing Python Related code is in Python database Related to database management libraries module labels Apr 21, 2024
@tmszi tmszi added bug Something isn't working backport to 8.3 labels Apr 21, 2024
@nilason
Copy link
Contributor

nilason commented Apr 22, 2024

I wonder if this shouldn't be approached in a different way. There is C API (driver specific) for this (db_begin_transaction(), db_commit_transaction()).

Anyways, it should have been START TRANSACTION and COMMIT, not BEGIN TRANSACTION and END TRANSACTION.

@tmszi
Copy link
Member Author

tmszi commented Apr 22, 2024

Anyways, it should have been START TRANSACTION and COMMIT, not BEGIN TRANSACTION and END TRANSACTION.

or BEGIN as alias for START TRANSACTION.

@nilason
Copy link
Contributor

nilason commented Apr 22, 2024

Anyways, it should have been START TRANSACTION and COMMIT, not BEGIN TRANSACTION and END TRANSACTION.

or BEGIN as alias for START TRANSACTION.

Yes, for the drivers that support it. You may take a look at how this is implemented for the different drivers in db/drivers/*/execute.c files.

@tmszi
Copy link
Member Author

tmszi commented Apr 22, 2024

I wonder if this shouldn't be approached in a different way. There is C API (driver specific) for this (db_begin_transaction(), db_commit_transaction()).

Yes you are right we can refactor it to better implementation on the low C lang level.

@github-actions github-actions bot added the C Related code is in C label Apr 22, 2024
@tmszi tmszi force-pushed the fix-sql-transaction-syntax-compatible-with-all-db-backends branch from ad77c20 to 6e66ee9 Compare April 22, 2024 10:04
@nilason
Copy link
Contributor

nilason commented Apr 22, 2024

Injecting sql code in db.execute breaks current behaviour, so that is not a good option. I was originally thinking of directly use C API in Python, like in:

def _deleteRecords(self, cats):

or
def CopyCats(self, fromId, toId, copyAttrb=False):

but that will require quite a lot of rewriting.

But you could perhaps use:
https://github.com/OSGeo/grass/blob/7413740dd81c11c2909ad10e7c3161fc097088f9/python/grass/script/db.py

def db_begin_transaction(driver):

@tmszi tmszi marked this pull request as draft April 22, 2024 18:51
@tmszi tmszi marked this pull request as ready for review April 23, 2024 10:35
@nilason
Copy link
Contributor

nilason commented Apr 23, 2024

I like where this is going. Something like this is what I had in mind, although it is way beyond the original intent of this PR. But I don't mind. Allows for more flexibility and control using C API directly, than via the module db.execute.
Not sure what to do about the change of behaviour of db_commit_transaction(API break).
I can also imagine making this a class, reducing the need to pass driver, database etc to every function call, and possibility to push sql commands (instead of building a string)... but before you put more work into this let us ask for the general opinion of this change by e.g. @petrasovaa, @wenzeslaus, @marisn.

@wenzeslaus
Copy link
Member

I also would like to replace putting the strings together by something better given our C database API and Python database APIs. While alternatives exists and some are employed in the code already, using the C library directly through C types is a straightforward option.

The API change is a potential issue. How big, I don't know, I'm guessing not big. Still, breaking it seems wrong. You also mentioned the issue of passing multiple parameters. I would certainly try how this would look as a class. This would be one way to avoid the change in the API. Perhaps following PEP 249 – Python Database API Specification or mimicking relevant parts of an existing SQL database Python API (Psycopg, sqlite3, SQLAlchemy, ...) would be good. Ideally, such API would actually hide whatever is happening in the background (constructing string for db.execute, passing to a native wrapper like sqlite3 or passing directly, or through a subprocess, to C API).

While when ctypes works, everything is just perfect, the experience is that something is often missing from the things which need to be in place for C API to work in Python. Hence, we have all the lazy imports in this PR and elsewhere. That's a thing which can be gradually improved, though. The many updates to ctypes lately were certainly helpful. Switching to Filesystem Hierarchy Standard might be another update which would help here ([GRASS-dev] GRASS 8.0 support in GDAL and QGIS).

I'm curious what others think.

@marisn
Copy link
Contributor

marisn commented May 3, 2024

I also would like to replace putting the strings together by something better given our C database API and Python database APIs. While alternatives exists and some are employed in the code already, using the C library directly through C types is a straightforward option.

Proper prepared statements are way to go but lets take one step at a time (that would require a new C and Python API).

The API change is a potential issue. How big, I don't know, I'm guessing not big. Still, breaking it seems wrong.

This wouldn't be the first time when we break API on a minor release. Taking into account that this is not the most commonly used functionality, it fixes compatibility with one of our supported back-ends, I would not cry over this.

@echoix
Copy link
Member

echoix commented Jun 3, 2024

Is this still planned for the due 8.4.0 release? If so, what is missing?

@nilason
Copy link
Contributor

nilason commented Jun 6, 2024

093c461: great initiative!

@tmszi tmszi force-pushed the fix-sql-transaction-syntax-compatible-with-all-db-backends branch from 093c461 to cc72ad3 Compare June 6, 2024 13:30
python/grass/script/db.py Outdated Show resolved Hide resolved
Copy link
Member

@wenzeslaus wenzeslaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I have doubts about reliability of ctypes interface (I guess too many bad experiences in the past), I appreciate the whole effort and the class makes sense.

python/grass/script/db.py Outdated Show resolved Hide resolved
python/grass/script/db.py Show resolved Hide resolved
scripts/v.db.addcolumn/v.db.addcolumn.py Outdated Show resolved Hide resolved
scripts/v.db.dropcolumn/v.db.dropcolumn.py Outdated Show resolved Hide resolved
@wenzeslaus
Copy link
Member

While very valuable, we can't fit this into 8.4, moving milestone to 8.5. I hope that's okay.

@wenzeslaus wenzeslaus modified the milestones: 8.4.0, 8.5.0 Jun 10, 2024
@tmszi
Copy link
Member Author

tmszi commented Jun 10, 2024

All suggestions was incorporated into commit no 072d0be.

@neteler neteler added backport to 8.4 PR needs to be backported to release branch 8.4 and removed backport to 8.3 labels Jun 14, 2024
@wenzeslaus wenzeslaus removed the backport to 8.4 PR needs to be backported to release branch 8.4 label Jun 15, 2024
@echoix
Copy link
Member

echoix commented Jul 5, 2024

There's now some conflicts to solve here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working C Related code is in C database Related to database management libraries module Python Related code is in Python vector Related to vector data processing
7 participants