id,node_id,number,title,user,state,locked,assignee,milestone,comments,created_at,updated_at,closed_at,author_association,pull_request,body,repo,type,active_lock_reason,performed_via_github_app,reactions,draft,state_reason
1353189941,I_kwDOCGYnMM5QqAo1,475,table.default_values introspection property,9599,closed,0,,8355157,1,2022-08-27T22:33:31Z,2022-08-27T22:44:46Z,2022-08-27T22:43:02Z,OWNER,,"> Interesting challenge with `default_value`: I need to be able to tell if the default values passed to `.create()` differ from those in the database already.
>
> Introspecting that is a bit tricky:
>
> ```pycon
> >>> import sqlite_utils
> >>> db = sqlite_utils.Database(memory=True)
> >>> db[""blah""].create({""id"": int, ""name"": str}, not_null=(""name"",), defaults={""name"": ""bob""})
>
> >>> db[""blah""].columns
> [Column(cid=0, name='id', type='INTEGER', notnull=0, default_value=None, is_pk=0), Column(cid=1, name='name', type='TEXT', notnull=1, default_value=""'bob'"", is_pk=0)]
> ```
> Note how a default value of the Python string `bob` is represented in the results of `PRAGMA table_info()` as `default_value=""'bob'""` - it's got single quotes added to it!
>
> So comparing default values from introspecting the database needs me to first parse that syntax. This may require a new table introspection method.
_Originally posted by @simonw in https://github.com/simonw/sqlite-utils/issues/468#issuecomment-1229279539_",140912432,issue,,,"{""url"": ""https://api.github.com/repos/simonw/sqlite-utils/issues/475/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed
1199158210,I_kwDOCGYnMM5HebPC,423,.extract() doesn't set foreign key when extracted columns contain NULL value,37447552,closed,0,,,1,2022-04-10T20:05:30Z,2022-08-27T14:45:04Z,2022-08-27T14:45:04Z,NONE,,"I've run into an issue with `extract` and I don't believe this is the intended behaviour.
I'm working with a database with music listening information. Currently it has one large table `listens` that contains all information. I'm trying to normalize the database by extracting relevant columns to separate tables (`artists`, `tracks`, `albums`). Not every track has an album.
A simplified demonstration with just `track_title` and `album_title` columns:
```ipython
In [1]: import sqlite_utils
In [2]: db = sqlite_utils.Database(memory=True)
In [3]: db[""listens""].insert_all([
...: {""id"": 1, ""track_title"": ""foo"", ""album_title"": ""bar""},
...: {""id"": 2, ""track_title"": ""baz"", ""album_title"": None}
...: ], pk=""id"")
Out[3]:
```
The track in the first row has an album, the second track doesn't. Now I extract album information into a separate column:
```ipython
In [4]: db[""listens""].extract(columns=[""album_title""], table=""albums"", fk_column=""album_id"")
Out[4]:
In [5]: list(db[""albums""].rows)
Out[5]: [{'id': 1, 'album_title': 'bar'}, {'id': 2, 'album_title': None}]
In [6]: list(db[""listens""].rows)
Out[6]:
[{'id': 1, 'track_title': 'foo', 'album_id': 1},
{'id': 2, 'track_title': 'baz', 'album_id': None}]
```
This behaves as expected -- the `album` table contains entries for both the existing album and the NULL album. The `listens` table has a foreign key only for the first row (since the album in the second row was empty).
Now I want to extract the track information as well. Album information belongs to the track so I want to extract both columns to a new table.
```ipython
In [7]: db[""listens""].extract(columns=[""track_title"", ""album_id""], table=""tracks"", fk_column=""track_id"")
Out[7]:
In [8]: list(db[""tracks""].rows)
Out[8]:
[{'id': 1, 'track_title': 'foo', 'album_id': 1},
{'id': 2, 'track_title': 'baz', 'album_id': None}]
In [9]: list(db[""listens""].rows)
Out[9]: [{'id': 1, 'track_id': 1}, {'id': 2, 'track_id': None}]
```
Extracting to the `tracks` table worked fine (both tracks are present with correct columns). However, the `listens` table only has a foreign key to the newly created tracks for the first row, the foreign key in the second row is NULL.
Changing the order of extracts doesn't help.
I poked around in the source a bit and I believe [this line](https://github.com/simonw/sqlite-utils/blob/433813612ff9b4b501739fd7543bef0040dd51fe/sqlite_utils/db.py#L1737) (essentially comparing `NULL = NULL`) is the problem, but I don't know enough about SQL to create a reliable fix myself.",140912432,issue,,,"{""url"": ""https://api.github.com/repos/simonw/sqlite-utils/issues/423/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed
1352953535,PR_kwDOCGYnMM4950Az,473,Support entrypoints for `--load-extension`,9599,closed,0,,,1,2022-08-27T05:53:59Z,2022-08-27T05:55:52Z,2022-08-27T05:55:47Z,OWNER,simonw/sqlite-utils/pulls/473,"Refs #470
----
:books: Documentation preview :books:: https://sqlite-utils--473.org.readthedocs.build/en/473/
",140912432,pull,,,"{""url"": ""https://api.github.com/repos/simonw/sqlite-utils/issues/473/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",0,
1352931464,I_kwDOCGYnMM5QpBiI,469,sqlite-utils rows --order option,9599,closed,0,,8355157,1,2022-08-27T03:49:51Z,2022-08-27T04:30:49Z,2022-08-27T04:10:32Z,OWNER,,"For consistency with `search`: https://sqlite-utils.datasette.io/en/stable/cli-reference.html#search
```
-o, --order TEXT Order by ('column' or 'column desc')
```
I wanted to run `sqlite-utils rows db.db mytable --order 'rowid desc'` to see the most recently imported rows.",140912432,issue,,,"{""url"": ""https://api.github.com/repos/simonw/sqlite-utils/issues/469/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed
1320243134,I_kwDOCGYnMM5OsU--,458,Support custom names for registered functions,9599,closed,0,,8355157,1,2022-07-28T00:13:00Z,2022-08-27T03:56:01Z,2022-07-28T00:13:57Z,OWNER,,"In this example:
```python
@db.register_function
def reverse_string(s):
return """".join(reversed(list(s)))
print(db.execute('select reverse_string(""hello"")').fetchone()[0])
```
There's currently no way to over-ride the automatically selected name for the SQL function.",140912432,issue,,,"{""url"": ""https://api.github.com/repos/simonw/sqlite-utils/issues/458/reactions"", ""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,completed