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

.delete_where() does not auto-commit (unlike .insert() or .upsert()) #159

Open
spdkils opened this issue Sep 16, 2020 · 10 comments
Open

.delete_where() does not auto-commit (unlike .insert() or .upsert()) #159

spdkils opened this issue Sep 16, 2020 · 10 comments
Labels
bug Something isn't working python-library

Comments

@spdkils
Copy link

spdkils commented Sep 16, 2020

When you use the delete_where() function on a table, it never commits....

Is that intentional?

@simonw
Copy link
Owner

simonw commented Sep 16, 2020

See #121 - I need to think harder about how this all interacts with transactions.

You can do this:

with db.conn:
    db["mytable"].delete_where()

But that should be documented and maybe rethought.

@spdkils
Copy link
Author

spdkils commented Sep 16, 2020

I appreciate the response, it's just unexpected.

If I insert, it commits, if I update it commits, if I upsert it commits... if I delete.. it doesn't???
Confused me...

I did just db commit it... But it's confusing.

@simonw
Copy link
Owner

simonw commented Sep 16, 2020

Yeah I'm going to class this as a bug - that's definitely confusing.

@simonw simonw added the bug Something isn't working label Sep 16, 2020
@simonw simonw changed the title delete_where does not commit... delete_where does not auto-commit (unlike insert or upsert) Sep 16, 2020
@simonw simonw changed the title delete_where does not auto-commit (unlike insert or upsert) .delete_where() does not auto-commit (unlike .insert() or .upsert()) Sep 16, 2020
@simonw
Copy link
Owner

simonw commented Sep 16, 2020

Independent of the transaction changes in #121 I may be able to check self.conn.in_transaction to see if a transaction is active and, if one is NOT active, execute the delete inside of one. https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.in_transaction

@simonw
Copy link
Owner

simonw commented Sep 16, 2020

That's strange... this test here doesn't manually commit a transaction and passes:

def test_delete_where(fresh_db):
table = fresh_db["table"]
for i in range(1, 11):
table.insert({"id": i}, pk="id")
assert 10 == table.count
table.delete_where("id > ?", [5])
assert 5 == table.count

@simonw
Copy link
Owner

simonw commented Sep 16, 2020

@spdkils can you share a minimal code example that exhibits the behavior you're seeing?

@limar
Copy link

limar commented Mar 18, 2021

I confirm the bug. Happens for me in version 3.6. I use the call to delete all the records:
table.delete_where()
This does not delete anything.

I see that delete() method DOES use context manager with self.db.conn: which should help. You may want to align the code of both methods.

@dracos
Copy link

dracos commented Apr 27, 2022

Just stumbled across this, wondering why none of my deletes were working.

@dracos
Copy link

dracos commented Apr 1, 2023

In a related issue, nearly a year later I just stumbled across this again, as I wondered why none of my rebuild-fts were rebuilding. It looks like: disable_fts in db.py commits; enable_fts partly commits except the last step (due to executescript committing a pending transaction); rebuild_fts won't commit unless manually done as above with e.g. a context manager.

NotJoeMartinez added a commit to NotJoeMartinez/yt-fts that referenced this issue May 29, 2023
sqlite_utils won't commit changes when deleting records in
`delete_channel`, might be something to do with the triggers added by
full text search.

Seems to be a known issue with the package
- simonw/sqlite-utils#315
- simonw/sqlite-utils#159

It doesn't seem to have a problem effecting the rows within the function
but the changes don't commit.
```python
    db = Database(db_name)
    cur  = db.execute(f"DELETE FROM Channels WHERE channel_id = ?", [channel_id])
    print(f"channels: {cur.rowcount}")
    cur = db.execute(f"DELETE FROM Subtitles WHERE video_id IN (SELECT video_id FROM Videos WHERE channel_id = ?)", [channel_id])
    print(f"subs: {cur.rowcount}")
    cur = db.execute(f"DELETE FROM Videos WHERE channel_id = ?", [channel_id])
    print(f"vids: {cur.rowcount}")

    # check if effectively deleted
    cur = db.execute(f"SELECT * FROM Channels WHERE channel_id = ?", [channel_id])
    print("channels after: ", cur, cur.fetchall())
    cur = db.execute(f"SELECT * FROM Videos WHERE channel_id = ?", [channel_id])
    print("Vids after", cur, cur.fetchall())
    cur = db.execute(f"SELECT * FROM Videos WHERE channel_id = ?", [channel_id])
```

other thing I tried:
```python
    db = Database(db_name)
    db["Channels"].delete_where("channel_id = ?", [channel_id])
    db["Subtitles"].delete_where("video_id IN (SELECT video_id FROM Videos WHERE channel_id = ?)", [channel_id])
    db["Videos"].delete_where("channel_id = ?", [channel_id])
```

Anyway there doesn't seem to be any issues with using python sqlite3 for
the delete operations
@learning4life
Copy link
Contributor

@spdkils can you share a minimal code example that exhibits the behavior you're seeing?

Example to show the bug still exists in Sqlite-utils v3.36

Create test datataset

sqlite-utils insert global.db power_plants 'global_power_plant_database.csv' --csv

table.delete_where() with no other arguments will not delete every row in the table.

import sqlite_utils
db = sqlite_utils.Database("global.db")
db["power_plants"].count_where("country > ?", [1])
db["power_plants"].delete_where()
db["power_plants"].count_where("country > ?", [1])

Counting rows shows not deleted rows

import sqlite_utils
db = sqlite_utils.Database("global.db")
db["power_plants"].count_where("country > ?", [1])

Results from running above code in bash using docker

[root@b5441fc4c92e DockerSqliteUtils]# sqlite-utils insert global.db power_plants 'global_power_plant_database.csv' --csv
  [###################################-]   99%  00:00:00
[root@b5441fc4c92e DockerSqliteUtils]# python3
Python 3.9.19 (main, May 20 2024, 05:19:58) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite_utils
>>> db = sqlite_utils.Database("global.db")
>>> db["power_plants"].count_where("country > ?", [1])
33643
>>> db["power_plants"].delete_where()
<Table power_plants (country, country_long, name, gppd_idnr, capacity_mw, latitude, longitude, primary_fuel, other_fuel1, other_fuel2, other_fuel3, commissioning_year, owner, source, url, geolocation_source, wepp_id, year_of_capacity_data, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, generation_data_source, estimated_generation_gwh)>
>>> db["power_plants"].count_where("country > ?", [1])
0
>>> exit()
[root@b5441fc4c92e DockerSqliteUtils]# python3
Python 3.9.19 (main, May 20 2024, 05:19:58) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite_utils
>>> db = sqlite_utils.Database("global.db")
>>> db["power_plants"].count_where("country > ?", [1])
33643
>>> 

learning4life added a commit to learning4life/sqlite-utils that referenced this issue Jul 3, 2024
Documented the use of delete_where, as shown in simonw#159
simonw pushed a commit that referenced this issue Jul 18, 2024
Documented the use of delete_where, as shown in #159
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working python-library
Projects
None yet
Development

No branches or pull requests

5 participants