issue_comments
10,495 rows sorted by updated_at descending
This data as json, CSV (advanced)
created_at (date) >1000 ✖
- 2021-03-22 66
- 2021-11-19 60
- 2020-10-15 52
- 2020-09-22 51
- 2020-10-30 49
- 2022-10-26 47
- 2022-03-21 46
- 2020-12-18 43
- 2020-06-09 42
- 2022-10-27 42
- 2020-06-18 41
- 2022-10-25 41
- 2022-01-09 40
- 2022-06-14 40
- 2020-05-27 39
- 2020-10-20 39
- 2021-11-16 39
- 2021-12-16 39
- 2020-12-30 38
- 2020-10-09 36
- 2021-11-20 36
- 2022-01-20 36
- 2022-03-19 36
- 2020-09-15 34
- 2021-11-29 34
- 2020-06-08 33
- 2021-01-04 33
- 2021-05-27 33
- 2022-02-06 33
- 2020-06-01 32
- 2022-03-05 32
- 2019-06-24 31
- 2020-09-21 31
- 2021-08-13 31
- 2022-04-28 31
- 2022-08-27 31
- 2019-06-23 30
- 2021-08-09 30
- 2018-04-16 29
- 2020-06-16 29
- 2020-10-16 29
- 2021-12-18 29
- 2020-02-14 28
- 2020-06-06 28
- 2020-11-24 28
- 2020-12-31 28
- 2021-01-03 28
- 2021-12-19 28
- 2022-02-02 28
- 2022-05-20 28
- 2017-11-13 27
- 2017-11-14 27
- 2020-03-23 27
- 2020-05-30 27
- 2022-09-26 27
- 2022-10-24 27
- 2021-02-14 26
- 2021-06-16 26
- 2022-04-26 26
- 2022-07-15 26
- 2022-10-14 26
- 2020-06-29 25
- 2020-09-24 25
- 2020-12-29 25
- 2021-01-25 25
- 2021-06-03 25
- 2022-02-03 25
- 2022-03-15 25
- 2020-02-24 24
- 2020-04-18 24
- 2020-08-18 24
- 2020-09-14 24
- 2020-10-31 24
- 2022-08-14 24
- 2017-11-19 23
- 2020-05-03 23
- 2020-10-19 23
- 2020-10-29 23
- 2021-02-18 23
- 2021-11-14 23
- 2020-05-31 22
- 2020-09-30 22
- 2020-11-05 22
- 2020-11-30 22
- 2020-12-17 22
- 2022-09-15 22
- 2020-05-06 21
- 2020-05-28 21
- 2021-02-25 21
- 2021-06-19 21
- 2021-08-18 21
- 2021-12-17 21
- 2022-01-06 21
- 2022-03-11 21
- 2022-04-27 21
- 2022-10-30 21
- 2022-11-03 21
- 2017-11-16 20
- 2018-05-27 20
- 2018-07-10 20
- 2019-05-03 20
- 2019-05-11 20
- 2019-11-11 20
- 2020-03-24 20
- 2020-06-11 20
- 2020-06-23 20
- 2020-07-08 20
- 2020-09-07 20
- 2020-10-11 20
- 2020-10-23 20
- 2021-01-06 20
- 2021-02-20 20
- 2021-03-04 20
- 2021-08-24 20
- 2022-01-26 20
- 2022-05-02 20
- 2022-09-06 20
- 2019-11-04 19
- 2020-03-25 19
- 2020-05-02 19
- 2020-08-12 19
- 2021-10-24 19
- 2021-12-11 19
- 2022-01-08 19
- 2022-02-18 19
- 2022-03-07 19
- 2022-08-23 19
- 2018-04-09 18
- 2018-05-22 18
- 2019-05-23 18
- 2019-06-13 18
- 2019-06-22 18
- 2020-03-26 18
- 2020-04-05 18
- 2020-05-01 18
- 2020-05-04 18
- 2020-05-05 18
- 2020-06-03 18
- 2020-06-13 18
- 2020-07-01 18
- 2020-09-23 18
- 2020-10-21 18
- 2021-01-01 18
- 2021-05-23 18
- 2021-05-29 18
- 2021-08-10 18
- 2022-01-13 18
- 2022-02-07 18
- 2022-10-07 18
- 2017-10-24 17
- 2018-05-24 17
- 2018-06-21 17
- 2020-06-28 17
- 2020-08-28 17
- 2020-12-09 17
- 2021-02-12 17
- 2021-03-23 17
- 2021-03-29 17
- 2021-08-19 17
- 2021-12-23 17
- 2022-09-05 17
- 2022-09-07 17
- 2022-09-27 17
- 2017-10-23 16
- 2017-11-11 16
- 2018-05-28 16
- 2019-03-15 16
- 2020-04-27 16
- 2020-05-08 16
- 2020-05-10 16
- 2020-08-11 16
- 2020-08-16 16
- 2020-10-14 16
- 2020-11-29 16
- 2020-12-03 16
- 2021-03-27 16
- 2021-06-05 16
- 2021-07-10 16
- 2021-07-31 16
- 2021-11-15 16
- 2022-03-20 16
- 2022-11-01 16
- 2017-11-15 15
- 2018-05-16 15
- 2018-06-18 15
- 2019-10-14 15
- 2020-04-29 15
- 2020-05-11 15
- 2020-06-05 15
- 2020-06-10 15
- 2020-06-12 15
- 2020-08-09 15
- 2020-09-17 15
- 2020-10-22 15
- 2021-01-05 15
- 2021-02-19 15
- 2021-05-31 15
- 2021-06-26 15
- 2022-01-11 15
- 2017-12-10 14
- 2019-03-17 14
- 2019-07-05 14
- 2020-02-04 14
- 2020-06-07 14
- 2020-09-12 14
- 2020-10-08 14
- 2020-10-25 14
- 2020-11-06 14
- 2020-12-16 14
- 2021-08-01 14
- 2021-08-28 14
- 2022-01-21 14
- 2022-02-05 14
- 2017-11-17 13
- 2018-03-28 13
- 2018-04-08 13
- 2019-02-24 13
- 2019-07-08 13
- 2019-11-12 13
- 2019-11-13 13
- 2020-02-25 13
- 2020-05-20 13
- 2020-09-03 13
- 2020-10-10 13
- 2021-04-03 13
- 2021-06-06 13
- 2021-12-20 13
- 2022-03-06 13
- 2022-04-24 13
- 2022-06-13 13
- 2022-11-04 13
- 2017-10-25 12
- 2017-11-12 12
- 2018-04-17 12
- 2019-04-12 12
- 2019-10-16 12
- 2019-11-09 12
- 2020-02-23 12
- 2020-04-16 12
- 2020-04-26 12
- 2020-04-30 12
- 2020-10-17 12
- 2020-12-04 12
- 2020-12-14 12
- 2021-02-26 12
- 2021-05-19 12
- 2021-06-15 12
- 2021-07-16 12
- 2022-01-14 12
- 2017-12-07 11
- 2018-05-29 11
- 2018-05-31 11
- 2018-07-24 11
- 2019-05-16 11
- 2019-06-30 11
- 2019-10-11 11
- 2019-10-17 11
- 2019-11-08 11
- 2020-02-22 11
- 2020-06-02 11
- 2020-06-30 11
- 2020-07-18 11
- 2020-07-27 11
- 2020-08-30 11
- 2020-09-28 11
- 2020-11-02 11
- 2020-11-12 11
- 2020-12-12 11
- 2021-02-27 11
- 2021-04-02 11
- 2021-04-04 11
- 2021-04-05 11
- 2021-06-02 11
- 2021-06-18 11
- 2021-08-12 11
- 2021-12-10 11
- 2021-12-22 11
- 2022-01-10 11
- 2022-02-09 11
- 2022-09-14 11
- 2018-04-14 10
- 2018-05-23 10
- 2018-06-15 10
- 2018-06-16 10
- 2019-04-29 10
- 2019-07-07 10
- 2019-07-19 10
- 2019-11-03 10
- 2019-11-26 10
- 2020-04-02 10
- 2020-06-24 10
- 2020-07-26 10
- 2020-08-21 10
- 2020-09-08 10
- 2021-05-24 10
- 2021-08-02 10
- 2021-08-17 10
- 2022-01-12 10
- 2022-01-19 10
- 2022-03-23 10
- 2017-12-09 9
- 2018-04-15 9
- 2018-04-20 9
- 2018-11-05 9
- 2019-05-28 9
- 2019-06-25 9
- 2020-02-13 9
- 2020-03-08 9
- 2020-03-20 9
- 2020-04-06 9
- 2020-04-13 9
- 2020-04-28 9
- 2020-05-07 9
- 2020-07-24 9
- 2020-09-02 9
- 2020-12-19 9
- 2021-01-02 9
- 2021-01-22 9
- 2021-02-02 9
- 2021-03-10 9
- 2021-03-20 9
- 2021-05-28 9
- 2021-06-22 9
- 2021-07-08 9
- 2021-07-15 9
- 2021-12-12 9
- 2022-02-04 9
- 2022-03-08 9
- 2022-04-13 9
- 2022-05-03 9
- 2022-05-17 9
- 2022-06-21 9
- 2022-07-05 9
- 2022-07-18 9
- 2022-08-18 9
- 2022-09-28 9
- 2017-11-29 8
- 2017-11-30 8
- 2018-03-27 8
- 2018-03-30 8
- 2018-05-25 8
- 2019-05-19 8
- 2019-05-21 8
- 2019-05-25 8
- 2019-05-29 8
- 2019-06-15 8
- 2019-07-20 8
- 2019-10-21 8
- 2020-01-31 8
- 2020-02-16 8
- 2020-03-16 8
- 2020-04-10 8
- 2020-04-21 8
- 2020-06-14 8
- 2020-06-21 8
- 2020-07-02 8
- 2020-07-31 8
- 2020-08-19 8
- 2020-10-01 8
- 2020-10-12 8
- 2021-01-12 8
- 2021-01-24 8
- 2021-02-15 8
- 2021-02-23 8
- 2021-06-07 8
- 2021-07-02 8
- 2021-07-11 8
- 2021-09-23 8
- 2021-10-08 8
- 2021-10-13 8
- 2021-12-14 8
- 2022-01-07 8
- 2022-02-16 8
- 2022-03-24 8
- 2022-03-25 8
- 2022-06-20 8
- 2022-08-21 8
- 2022-09-02 8
- 2022-10-18 8
- 2022-10-28 8
- 2017-11-09 7
- 2017-11-20 7
- 2017-11-21 7
- 2018-06-17 7
- 2018-07-26 7
- 2019-01-28 7
- 2019-05-02 7
- 2019-06-09 7
- 2019-06-18 7
- 2019-10-07 7
- 2019-10-18 7
- 2019-10-30 7
- 2020-01-29 7
- 2020-02-27 7
- 2020-03-06 7
- 2020-03-21 7
- 2020-03-31 7
- 2020-04-01 7
- 2020-04-15 7
- 2020-04-24 7
- 2020-05-15 7
- 2020-05-21 7
- 2020-05-29 7
- 2020-06-20 7
- 2020-07-06 7
- 2020-08-29 7
- 2020-09-16 7
- 2020-10-24 7
- 2020-10-27 7
- 2020-11-04 7
- 2020-11-07 7
- 2021-01-18 7
- 2021-02-11 7
- 2021-02-22 7
- 2021-05-17 7
- 2021-07-14 7
- 2021-07-25 7
- 2021-07-30 7
- 2021-08-04 7
- 2021-08-14 7
- 2021-08-25 7
- 2021-09-21 7
- 2021-09-22 7
- 2021-11-17 7
- 2021-11-30 7
- 2021-12-01 7
- 2021-12-07 7
- 2021-12-13 7
- 2022-02-08 7
- 2022-03-13 7
- 2022-03-14 7
- 2022-03-17 7
- 2022-04-08 7
- 2022-04-11 7
- 2022-04-21 7
- 2022-09-01 7
- 2022-09-09 7
- 2022-09-29 7
- 2022-10-08 7
- 2022-11-02 7
- 2017-10-26 6
- 2017-11-22 6
- 2017-11-23 6
- 2017-12-08 6
- 2018-04-03 6
- 2018-04-18 6
- 2018-04-26 6
- 2018-05-12 6
- 2018-05-13 6
- 2018-05-14 6
- 2018-05-21 6
- 2018-05-26 6
- 2018-06-04 6
- 2018-07-12 6
- 2019-04-13 6
- 2019-07-03 6
- 2019-07-09 6
- 2019-07-11 6
- 2019-07-14 6
- 2019-09-02 6
- 2019-11-01 6
- 2019-11-07 6
- 2019-12-18 6
- 2019-12-22 6
- 2020-02-15 6
- 2020-03-05 6
- 2020-03-14 6
- 2020-03-22 6
- 2020-04-23 6
- 2020-06-22 6
- 2020-06-27 6
- 2020-09-01 6
- 2020-09-09 6
- 2020-10-06 6
- 2020-10-26 6
- 2020-12-13 6
- 2021-01-15 6
- 2021-03-09 6
- 2021-03-12 6
- 2021-03-21 6
- 2021-03-28 6
- 2021-06-01 6
- 2021-06-11 6
- 2021-07-22 6
- 2021-08-08 6
- 2021-08-20 6
- 2021-08-23 6
- 2021-09-08 6
- 2021-10-07 6
- 2021-10-14 6
- 2021-11-28 6
- 2022-01-25 6
- 2022-03-02 6
- 2022-03-22 6
- 2022-04-25 6
- 2022-07-10 6
- 2022-07-20 6
- 2022-08-02 6
- 2022-09-23 6
- 2022-10-02 6
- 2022-10-12 6
- 2017-11-18 5
- 2017-11-27 5
- 2018-05-17 5
- 2018-05-30 5
- 2018-06-05 5
- 2018-07-11 5
- 2018-08-11 5
- 2018-09-19 5
- 2019-03-19 5
- 2019-06-28 5
- 2019-07-23 5
- 2019-07-24 5
- 2019-11-14 5
- 2019-11-27 5
- 2019-12-26 5
- 2020-01-30 5
- 2020-02-28 5
- 2020-03-27 5
- 2020-03-30 5
- 2020-04-17 5
- 2020-05-25 5
- 2020-06-19 5
- 2020-06-26 5
- 2020-07-30 5
- 2020-08-10 5
- 2020-08-15 5
- 2020-10-28 5
- 2020-11-13 5
- 2020-11-28 5
- 2020-12-01 5
- 2020-12-05 5
- 2020-12-08 5
- 2020-12-22 5
- 2020-12-23 5
- 2021-01-07 5
- 2021-01-17 5
- 2021-01-28 5
- 2021-01-29 5
- 2021-03-08 5
- 2021-03-18 5
- 2021-03-31 5
- 2021-06-12 5
- 2021-06-13 5
- 2021-06-14 5
- 2021-06-25 5
- 2021-08-05 5
- 2021-08-06 5
- 2021-08-07 5
- 2021-09-13 5
- 2021-12-06 5
- 2021-12-15 5
- 2022-02-15 5
- 2022-03-16 5
- 2022-03-26 5
- 2022-03-30 5
- 2022-04-22 5
- 2022-04-30 5
- 2022-07-27 5
- 2022-08-13 5
- 2022-08-28 5
- 2022-08-30 5
- 2022-08-31 5
- 2022-09-17 5
- 2022-09-22 5
- 2022-10-05 5
- 2022-10-13 5
- 2022-10-31 5
- 2017-11-10 4
- 2017-12-01 4
- 2017-12-04 4
- 2017-12-05 4
- 2018-04-11 4
- 2018-04-12 4
- 2018-06-28 4
- 2018-06-29 4
- 2018-07-13 4
- 2018-07-14 4
- 2018-07-18 4
- 2019-01-02 4
- 2019-01-17 4
- 2019-04-07 4
- 2019-04-11 4
- 2019-05-05 4
- 2019-05-09 4
- 2019-06-04 4
- 2019-07-04 4
- 2019-07-06 4
- 2019-07-22 4
- 2019-07-28 4
- 2019-08-17 4
- 2019-08-23 4
- 2019-09-03 4
- 2019-09-04 4
- 2019-10-13 4
- 2019-11-18 4
- 2019-11-19 4
- 2019-12-08 4
- 2019-12-27 4
- 2020-02-01 4
- 2020-02-29 4
- 2020-04-22 4
- 2020-05-12 4
- 2020-06-17 4
- 2020-07-16 4
- 2020-08-24 4
- 2020-09-11 4
- 2020-09-18 4
- 2020-09-20 4
- 2020-10-05 4
- 2020-10-07 4
- 2020-11-03 4
- 2020-11-15 4
- 2020-11-21 4
- 2020-12-02 4
- 2020-12-21 4
- 2020-12-24 4
- 2021-01-26 4
- 2021-03-05 4
- 2021-03-07 4
- 2021-04-29 4
- 2021-06-20 4
- 2021-06-23 4
- 2021-07-07 4
- 2021-07-18 4
- 2021-08-03 4
- 2021-08-26 4
- 2021-09-07 4
- 2021-10-18 4
- 2021-10-19 4
- 2021-10-30 4
- 2021-11-21 4
- 2021-11-22 4
- 2021-12-08 4
- 2022-02-11 4
- 2022-03-01 4
- 2022-03-18 4
- 2022-05-16 4
- 2022-05-27 4
- 2022-06-22 4
- 2022-07-02 4
- 2022-07-17 4
- 2022-08-15 4
- 2022-08-20 4
- 2022-09-19 4
- 2022-09-21 4
- 2022-10-06 4
- 2017-11-24 3
- 2017-12-02 3
- 2018-03-21 3
- 2018-04-13 3
- 2018-04-22 3
- 2018-05-03 3
- 2018-05-06 3
- 2018-05-11 3
- 2018-05-18 3
- 2018-06-20 3
- 2018-07-31 3
- 2018-08-12 3
- 2018-08-16 3
- 2018-08-28 3
- 2018-11-19 3
- 2019-01-10 3
- 2019-01-13 3
- 2019-01-18 3
- 2019-02-06 3
- 2019-02-23 3
- 2019-04-15 3
- 2019-04-18 3
- 2019-05-01 3
- 2019-05-13 3
- 2019-05-14 3
- 2019-05-20 3
- 2019-05-26 3
- 2019-05-27 3
- 2019-06-08 3
- 2019-06-11 3
- 2019-06-14 3
- 2019-07-12 3
- 2019-07-15 3
- 2019-09-14 3
- 2019-10-02 3
- 2019-10-06 3
- 2019-11-02 3
- 2019-11-15 3
- 2019-11-22 3
- 2019-12-03 3
- 2019-12-09 3
- 2020-01-10 3
- 2020-03-01 3
- 2020-03-02 3
- 2020-03-03 3
- 2020-03-09 3
- 2020-05-19 3
- 2020-05-26 3
- 2020-06-15 3
- 2020-07-21 3
- 2020-07-22 3
- 2020-08-01 3
- 2020-08-13 3
- 2020-08-25 3
- 2020-10-02 3
- 2020-11-01 3
- 2020-11-11 3
- 2020-11-22 3
- 2020-12-10 3
- 2021-01-09 3
- 2021-02-05 3
- 2021-02-06 3
- 2021-03-01 3
- 2021-03-13 3
- 2021-03-14 3
- 2021-03-19 3
- 2021-03-25 3
- 2021-04-20 3
- 2021-04-24 3
- 2021-04-28 3
- 2021-05-12 3
- 2021-05-18 3
- 2021-05-21 3
- 2021-06-09 3
- 2021-06-17 3
- 2021-06-27 3
- 2021-07-13 3
- 2021-07-26 3
- 2021-07-28 3
- 2021-09-04 3
- 2021-10-02 3
- 2021-10-12 3
- 2021-10-16 3
- 2021-10-28 3
- 2021-12-02 3
- 2022-01-15 3
- 2022-01-28 3
- 2022-02-23 3
- 2022-02-24 3
- 2022-03-12 3
- 2022-03-28 3
- 2022-03-29 3
- 2022-04-12 3
- 2022-04-14 3
- 2022-04-29 3
- 2022-07-07 3
- 2022-08-17 3
- 2022-09-16 3
- 2022-09-20 3
- 2022-09-24 3
- 2022-10-01 3
- 2022-10-03 3
- 2022-10-11 3
- 2022-10-29 3
- 2017-10-27 2
- 2017-11-06 2
- 2017-11-07 2
- 2017-11-26 2
- 2017-12-03 2
- 2018-01-09 2
- 2018-04-10 2
- 2018-04-19 2
- 2018-04-21 2
- 2018-05-04 2
- 2018-05-05 2
- 2018-05-15 2
- 2018-06-07 2
- 2018-08-06 2
- 2019-01-03 2
- 2019-01-11 2
- 2019-03-14 2
- 2019-03-20 2
- 2019-03-28 2
- 2019-03-31 2
- 2019-04-14 2
- 2019-04-21 2
- 2019-05-04 2
- 2019-05-24 2
- 2019-06-05 2
- 2019-06-06 2
- 2019-06-16 2
- 2019-07-16 2
- 2019-07-18 2
- 2019-07-26 2
- 2019-08-03 2
- 2019-08-31 2
- 2019-09-08 2
- 2019-10-10 2
- 2019-10-12 2
- 2019-10-24 2
- 2019-10-25 2
- 2019-10-27 2
- 2019-11-06 2
- 2019-11-10 2
- 2019-11-23 2
- 2019-11-29 2
- 2019-11-30 2
- 2019-12-01 2
- 2019-12-04 2
- 2019-12-31 2
- 2020-01-05 2
- 2020-01-06 2
- 2020-01-12 2
- 2020-01-19 2
- 2020-01-21 2
- 2020-02-03 2
- 2020-02-11 2
- 2020-02-12 2
- 2020-03-10 2
- 2020-03-17 2
- 2020-03-28 2
- 2020-04-04 2
- 2020-04-14 2
- 2020-04-19 2
- 2020-06-04 2
- 2020-07-03 2
- 2020-07-07 2
- 2020-07-09 2
- 2020-07-12 2
- 2020-07-17 2
- 2020-07-25 2
- 2020-07-29 2
- 2020-09-26 2
- 2020-09-27 2
- 2020-09-29 2
- 2020-11-09 2
- 2020-11-16 2
- 2020-11-17 2
- 2020-11-20 2
- 2020-11-25 2
- 2020-12-20 2
- 2020-12-27 2
- 2020-12-28 2
- 2021-01-08 2
- 2021-01-11 2
- 2021-01-14 2
- 2021-01-19 2
- 2021-01-30 2
- 2021-02-01 2
- 2021-02-03 2
- 2021-02-07 2
- 2021-02-08 2
- 2021-02-17 2
- 2021-02-28 2
- 2021-03-03 2
- 2021-03-15 2
- 2021-03-24 2
- 2021-04-12 2
- 2021-04-14 2
- 2021-04-18 2
- 2021-05-11 2
- 2021-05-26 2
- 2021-06-10 2
- 2021-06-21 2
- 2021-06-28 2
- 2021-07-09 2
- 2021-07-19 2
- 2021-07-24 2
- 2021-08-16 2
- 2021-08-22 2
- 2021-09-14 2
- 2021-09-28 2
- 2021-09-29 2
- 2021-10-05 2
- 2021-10-09 2
- 2021-10-20 2
- 2021-10-22 2
- 2021-10-26 2
- 2021-10-27 2
- 2021-11-01 2
- 2021-11-03 2
- 2021-11-13 2
- 2021-11-18 2
- 2021-11-23 2
- 2021-11-25 2
- 2021-12-04 2
- 2021-12-24 2
- 2021-12-26 2
- 2021-12-27 2
- 2022-02-13 2
- 2022-02-17 2
- 2022-03-09 2
- 2022-04-10 2
- 2022-05-12 2
- 2022-05-31 2
- 2022-06-15 2
- 2022-06-23 2
- 2022-06-28 2
- 2022-07-01 2
- 2022-07-04 2
- 2022-07-19 2
- 2022-07-22 2
- 2022-07-28 2
- 2022-08-16 2
- 2022-09-03 2
- 2022-09-08 2
- 2022-09-25 2
- 2022-10-04 2
- 2022-10-15 2
- 2017-10-30 1
- 2017-10-31 1
- 2017-11-04 1
- 2017-11-05 1
- 2017-12-21 1
- 2018-01-05 1
- 2018-01-08 1
- 2018-01-14 1
- 2018-01-23 1
- 2018-01-25 1
- 2018-02-26 1
- 2018-03-04 1
- 2018-03-05 1
- 2018-03-29 1
- 2018-04-06 1
- 2018-04-23 1
- 2018-04-24 1
- 2018-04-25 1
- 2018-05-19 1
- 2018-05-20 1
- 2018-06-01 1
- 2018-06-10 1
- 2018-06-24 1
- 2018-06-26 1
- 2018-06-27 1
- 2018-07-03 1
- 2018-07-08 1
- 2018-07-09 1
- 2018-07-16 1
- 2018-07-23 1
- 2018-07-27 1
- 2018-07-28 1
- 2018-08-01 1
- 2018-08-05 1
- 2018-08-13 1
- 2018-08-21 1
- 2018-08-31 1
- 2018-09-03 1
- 2018-09-05 1
- 2018-09-11 1
- 2018-09-21 1
- 2018-10-05 1
- 2018-10-08 1
- 2018-10-15 1
- 2018-10-22 1
- 2018-10-28 1
- 2018-11-15 1
- 2018-11-16 1
- 2018-11-20 1
- 2018-12-16 1
- 2018-12-19 1
- 2019-01-04 1
- 2019-01-06 1
- 2019-01-19 1
- 2019-02-02 1
- 2019-02-15 1
- 2019-02-16 1
- 2019-02-22 1
- 2019-02-26 1
- 2019-03-18 1
- 2019-03-21 1
- 2019-04-09 1
- 2019-04-10 1
- 2019-04-22 1
- 2019-04-30 1
- 2019-05-07 1
- 2019-05-10 1
- 2019-05-17 1
- 2019-05-30 1
- 2019-05-31 1
- 2019-06-07 1
- 2019-06-19 1
- 2019-06-26 1
- 2019-06-29 1
- 2019-07-17 1
- 2019-07-21 1
- 2019-07-25 1
- 2019-08-04 1
- 2019-08-07 1
- 2019-08-30 1
- 2019-09-10 1
- 2019-09-11 1
- 2019-09-12 1
- 2019-09-13 1
- 2019-09-21 1
- 2019-10-03 1
- 2019-10-04 1
- 2019-10-05 1
- 2019-10-08 1
- 2019-10-15 1
- 2019-10-20 1
- 2019-10-28 1
- 2019-10-29 1
- 2019-10-31 1
- 2019-11-05 1
- 2019-11-20 1
- 2019-11-21 1
- 2019-11-28 1
- 2019-12-02 1
- 2019-12-06 1
- 2019-12-10 1
- 2019-12-14 1
- 2019-12-15 1
- 2019-12-16 1
- …
user 319
- simonw 7,605
- codecov[bot] 173
- fgregg 68
- eyeseast 58
- russss 39
- psychemedia 34
- abdusco 26
- mroswell 22
- aborruso 19
- chrismp 18
- jacobian 14
- carlmjohnson 14
- brandonrobertz 14
- chapmanjacobd 14
- RhetTbull 14
- tballison 13
- wragge 12
- tsibley 11
- rixx 11
- stonebig 11
- dependabot[bot] 11
- frafra 10
- terrycojones 10
- rayvoelker 10
- maxhawkins 9
- clausjuhl 9
- bobwhitelock 9
- 20after4 8
- dracos 8
- UtahDave 8
- tomchristie 8
- bsilverm 8
- rgieseke 7
- zaneselvans 7
- mhalle 7
- zeluspudding 7
- cobiadigital 7
- amjith 6
- jefftriplett 6
- simonwiles 6
- khimaros 6
- CharlesNepote 6
- khusmann 5
- jaywgraves 5
- MarkusH 5
- dazzag24 5
- ocdtrekkie 5
- SteadBytes 5
- dependabot-preview[bot] 5
- jayvdb 4
- fs111 4
- bollwyvl 4
- ctb 4
- Btibert3 4
- dholth 4
- lovasoa 4
- r4vi 4
- jsfenfen 4
- glasnt 4
- jungle-boogie 4
- ColinMaudry 4
- kbaikov 4
- JBPressac 4
- nitinpaultifr 4
- Kabouik 4
- asg017 4
- henry501 4
- pjamargh 4
- benpickles 3
- frankieroberto 3
- obra 3
- janimo 3
- atomotic 3
- ghing 3
- pkoppstein 3
- yozlet 3
- yschimke 3
- philroche 3
- macropin 3
- camallen 3
- wsxiaoys 3
- johnfelipe 3
- mdrovdahl 3
- xrotwang 3
- Mjboothaus 3
- robroc 3
- betatim 3
- dufferzafar 3
- Florents-Tselai 3
- ashishdotme 3
- Segerberg 3
- hydrosquall 3
- blairdrummond 3
- jsancho-gpl 3
- kevindkeogh 3
- daniel-butler 3
- learning4life 3
- FabianHertwig 3
- polyrand 3
- garethr 2
- danp 2
- davidbgk 2
- nelsonjchen 2
- hubgit 2
- ftrain 2
- chrishas35 2
- tannewt 2
- ingenieroariel 2
- coleifer 2
- gavinband 2
- aviflax 2
- tholo 2
- cldellow 2
- mungewell 2
- frankier 2
- lchski 2
- tmaier 2
- gfrmin 2
- frosencrantz 2
- eads 2
- leafgarland 2
- glyph 2
- rafguns 2
- strada 2
- eelkevdbos 2
- ligurio 2
- n8henrie 2
- soobrosa 2
- nathancahill 2
- davidleejy 2
- bsmithgall 2
- willingc 2
- nattaylor 2
- durkie 2
- raynae 2
- wulfmann 2
- philshem 2
- bram2000 2
- zzeleznick 2
- chris48s 2
- plpxsk 2
- jeqo 2
- henrikek 2
- swyxio 2
- nickvazz 2
- aaronyih1 2
- luxint 2
- jussiarpalahti 2
- lagolucas 2
- chekos 2
- mattmalcher 2
- ad-si 2
- smithdc1 2
- justmars 2
- gsajko 2
- jcmkk3 2
- null92 2
- rachelmarconi 2
- tunguyenatwork 2
- LVerneyPEReN 2
- MichaelTiemannOSC 2
- anotherjesse 1
- jarib 1
- jokull 1
- fernand0 1
- dsisnero 1
- llimllib 1
- gijs 1
- blaine 1
- ashanan 1
- gravis 1
- nkirsch 1
- tomdyson 1
- mrchrisadams 1
- dkam 1
- harperreed 1
- nileshtrivedi 1
- furilo 1
- kindly 1
- adamwolf 1
- prabhur 1
- palfrey 1
- dmd 1
- rubenv 1
- Uninen 1
- carsonyl 1
- nryberg 1
- step21 1
- stefanocudini 1
- rcoup 1
- scoates 1
- hpk42 1
- annapowellsmith 1
- aslakr 1
- thorn0 1
- yurivish 1
- jmelloy 1
- Krazybug 1
- dvhthomas 1
- dckc 1
- phubbard 1
- sethvincent 1
- mcarpenter 1
- meatcar 1
- aitoehigie 1
- michaelmcandrew 1
- drewda 1
- stiles 1
- saulpw 1
- thadk 1
- robintw 1
- astrojuanlu 1
- ipmb 1
- steren 1
- aidansteele 1
- mikepqr 1
- 0x1997 1
- knutwannheden 1
- davidszotten 1
- kevboh 1
- eaubin 1
- yunzheng 1
- lfdebrux 1
- karlcow 1
- heyarne 1
- amitkoth 1
- ryanfox 1
- ryascott 1
- simonrjones 1
- mcint 1
- justinpinkney 1
- merwok 1
- mattkiefer 1
- virtadpt 1
- snth 1
- joshmgrant 1
- bcongdon 1
- nickdirienzo 1
- adamjonas 1
- hannseman 1
- kaihendry 1
- urbas 1
- brimstone 1
- adamchainz 1
- PabloLerma 1
- adipasquale 1
- heussd 1
- RayBB 1
- limar 1
- drkane 1
- Gagravarr 1
- agguser 1
- dyllan-to-you 1
- justinallen 1
- jordaneremieff 1
- wdccdw 1
- mustafa0x 1
- wpears 1
- progpow 1
- ltrgoddard 1
- costrouc 1
- jratike80 1
- ment4list 1
- ccorcos 1
- qqilihq 1
- OverkillGuy 1
- QAInsights 1
- secretGeek 1
- fkuhn 1
- jameslittle230 1
- Profpatsch 1
- dskrad 1
- kwladyka 1
- Carib0u 1
- fatihky 1
- phoenixjun 1
- JesperTreetop 1
- bapowell 1
- louispotok 1
- ChristopherWilks 1
- Maltazar 1
- eumiro 1
- wuhland 1
- foscoj 1
- dvot197007 1
- kokes 1
- RamiAwar 1
- csusanu 1
- rprimet 1
- metab0t 1
- spdkils 1
- sturzl 1
- robmarkcole 1
- jfeiwell 1
- coisnepe 1
- chmaynard 1
- sachaj 1
- bendnorman 1
- noklam 1
- GmGniap 1
- rdtq 1
- AnkitKundariya 1
- LucasElArruda 1
- duarteocarmo 1
- mattiaborsoi 1
- sarcasticadmin 1
- abeyerpath 1
- b0b5h4rp13 1
- Rik-de-Kort 1
- patricktrainer 1
- xmichele 1
- miuku 1
- thewchan 1
- publicmatt 1
- izzues 1
- thisismyfuckingusername 1
- kirajano 1
- knowledgecamp12 1
- McEazy2700 1
id | html_url | issue_url | node_id | user | created_at | updated_at ▲ | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
1304539296 | https://github.com/simonw/sqlite-utils/issues/235#issuecomment-1304539296 | https://api.github.com/repos/simonw/sqlite-utils/issues/235 | IC_kwDOCGYnMM5NwbCg | ryascott 559711 | 2022-11-05T12:40:12Z | 2022-11-05T12:40:12Z | NONE | I had the problem this morning when running:
I upgraded to:
and the error did not appear anymore. Hope this helps Ryan |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Extract columns cannot create foreign key relation: sqlite3.OperationalError: table sqlite_master may not be modified 810618495 | |
1304320521 | https://github.com/simonw/sqlite-utils/issues/511#issuecomment-1304320521 | https://api.github.com/repos/simonw/sqlite-utils/issues/511 | IC_kwDOCGYnMM5NvloJ | chapmanjacobd 7908073 | 2022-11-04T22:54:09Z | 2022-11-04T22:59:54Z | CONTRIBUTOR | I ran |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
[insert_all, upsert_all] IntegrityError: constraint failed 1436539554 | |
1304078945 | https://github.com/simonw/sqlite-utils/issues/511#issuecomment-1304078945 | https://api.github.com/repos/simonw/sqlite-utils/issues/511 | IC_kwDOCGYnMM5Nuqph | chapmanjacobd 7908073 | 2022-11-04T19:38:36Z | 2022-11-04T20:13:17Z | CONTRIBUTOR | Even more bizarre, the source db only has one record and the target table has no conflicting record:
I've been able to use this code successfully several times before so not sure what's causing the issue. I guess the way that I'm handling multiple databases is an issue, though it hasn't ever inserted into the source db, not sure what's different. The only reasonable explanation is that it is trying to insert into the source db from the source db for some reason? Or maybe sqlite3 is checking the source db for primary key violation because the table name is the same |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
[insert_all, upsert_all] IntegrityError: constraint failed 1436539554 | |
1302818784 | https://github.com/simonw/datasette/issues/1882#issuecomment-1302818784 | https://api.github.com/repos/simonw/datasette/issues/1882 | IC_kwDOBm6k_c5Np2_g | simonw 9599 | 2022-11-04T00:25:18Z | 2022-11-04T16:12:39Z | OWNER | On that basis I think the core API design should change to this:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`/db/-/create` API for creating tables 1435294468 | |
1303660293 | https://github.com/simonw/sqlite-utils/issues/50#issuecomment-1303660293 | https://api.github.com/repos/simonw/sqlite-utils/issues/50 | IC_kwDOCGYnMM5NtEcF | chapmanjacobd 7908073 | 2022-11-04T14:38:36Z | 2022-11-04T14:38:36Z | CONTRIBUTOR | where did you see the limit as 999? I believe the limit has been 32766 for quite some time. If you could detect which one this could speed up batch insert of some types of data significantly |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
"Too many SQL variables" on large inserts 473083260 | |
1303301786 | https://github.com/simonw/datasette/issues/1217#issuecomment-1303301786 | https://api.github.com/repos/simonw/datasette/issues/1217 | IC_kwDOBm6k_c5Nrs6a | mattmalcher 31312775 | 2022-11-04T11:37:52Z | 2022-11-04T11:37:52Z | NONE | All seems to work well, but there are some glitches to do with proxies, see #1883 . Excited to use this :) |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Possible to deploy as a python app (for Rstudio connect server)? 802513359 | |
1303299509 | https://github.com/simonw/datasette/issues/1217#issuecomment-1303299509 | https://api.github.com/repos/simonw/datasette/issues/1217 | IC_kwDOBm6k_c5NrsW1 | mattmalcher 31312775 | 2022-11-04T11:35:13Z | 2022-11-04T11:35:13Z | NONE | The following worked for deployment to RStudio / Posit Connect An app.py along the lines of: ```python from pathlib import Path from datasette.app import Datasette example_db = Path(file).parent / "data" / "example.db" use connect 'Content URL' setting here to set app to /datasette/ds = Datasette(files=[example_db], settings={"base_url": "/datasette/"}) ds._startup_invoked = True
ds_app = ds.app()
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Possible to deploy as a python app (for Rstudio connect server)? 802513359 | |
1302818153 | https://github.com/simonw/datasette/issues/1882#issuecomment-1302818153 | https://api.github.com/repos/simonw/datasette/issues/1882 | IC_kwDOBm6k_c5Np21p | simonw 9599 | 2022-11-04T00:23:58Z | 2022-11-04T00:23:58Z | OWNER | I made a decision here that this endpoint should also accept an optional |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`/db/-/create` API for creating tables 1435294468 | |
1302817807 | https://github.com/simonw/datasette/issues/1862#issuecomment-1302817807 | https://api.github.com/repos/simonw/datasette/issues/1862 | IC_kwDOBm6k_c5Np2wP | simonw 9599 | 2022-11-04T00:23:13Z | 2022-11-04T00:23:13Z | OWNER | I don't like this on |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Create a new table from one or more records, `sqlite-utils` style 1425011030 | |
1302817500 | https://github.com/simonw/datasette/issues/1862#issuecomment-1302817500 | https://api.github.com/repos/simonw/datasette/issues/1862 | IC_kwDOBm6k_c5Np2rc | simonw 9599 | 2022-11-04T00:22:31Z | 2022-11-04T00:22:31Z | OWNER | Maybe this is a feature added to the existing Bit weird that you can call that endpoint for a table that doesn't exist yet, but it fits the So perhaps the API looks like this:
That means I probably also need a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Create a new table from one or more records, `sqlite-utils` style 1425011030 | |
1302815105 | https://github.com/simonw/datasette/issues/1871#issuecomment-1302815105 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Np2GB | simonw 9599 | 2022-11-04T00:17:23Z | 2022-11-04T00:17:23Z | OWNER | I'll probably enhance it a bit more though, I want to provide a UI that lists all the tables you can explore and lets you click to pre-fill the forms with them. Though at that point what should I do about the other endpoints? Probably list those too. Gets a bit complex, especially with the row-level update and delete endpoints. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1302814693 | https://github.com/simonw/datasette/issues/1871#issuecomment-1302814693 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Np1_l | simonw 9599 | 2022-11-04T00:16:36Z | 2022-11-04T00:16:36Z | OWNER | I can close this issue once I fix it so it no longer hard-codes a potentially invalid example endpoint: |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1302813449 | https://github.com/simonw/datasette/issues/1881#issuecomment-1302813449 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5Np1sJ | simonw 9599 | 2022-11-04T00:14:07Z | 2022-11-04T00:14:07Z | OWNER | Tool is now live here: https://latest-1-0-dev.datasette.io/-/permissions Needs root perms, so access this first: https://latest-1-0-dev.datasette.io/login-as-root |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1302812918 | https://github.com/simonw/datasette/issues/1881#issuecomment-1302812918 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5Np1j2 | simonw 9599 | 2022-11-04T00:13:05Z | 2022-11-04T00:13:05Z | OWNER | Has tests now. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1302790013 | https://github.com/simonw/datasette/issues/1863#issuecomment-1302790013 | https://api.github.com/repos/simonw/datasette/issues/1863 | IC_kwDOBm6k_c5Npv99 | simonw 9599 | 2022-11-03T23:32:30Z | 2022-11-03T23:32:30Z | OWNER | I'm not going to allow updates to primary keys. If you need to do that, you can instead delete the record and then insert a new one with the new primary keys you wanted - or maybe use a custom SQL query. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a single record in an existing table 1425029242 | |
1294224185 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294224185 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NJEs5 | simonw 9599 | 2022-10-27T23:18:24Z | 2022-11-03T23:26:05Z | OWNER | So new API design is:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1302785086 | https://github.com/simonw/datasette/issues/1863#issuecomment-1302785086 | https://api.github.com/repos/simonw/datasette/issues/1863 | IC_kwDOBm6k_c5Npuw- | simonw 9599 | 2022-11-03T23:24:33Z | 2022-11-03T23:24:56Z | OWNER | Thinking more about validation: I'm considering if this should validate that columns which are defined as SQLite foreign keys are being updated to values that exist in those other tables. I like the sound of this. It seems like a sensible default behaviour for Datasette. And it fits with the fact that Datasette treats foreign keys specially elsewhere in the interface. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a single record in an existing table 1425029242 | |
1302760549 | https://github.com/simonw/datasette/issues/1863#issuecomment-1302760549 | https://api.github.com/repos/simonw/datasette/issues/1863 | IC_kwDOBm6k_c5Npoxl | simonw 9599 | 2022-11-03T22:43:04Z | 2022-11-03T23:21:31Z | OWNER | The
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a single record in an existing table 1425029242 | |
1302760382 | https://github.com/simonw/datasette/issues/1863#issuecomment-1302760382 | https://api.github.com/repos/simonw/datasette/issues/1863 | IC_kwDOBm6k_c5Npou- | simonw 9599 | 2022-11-03T22:42:47Z | 2022-11-03T22:42:47Z | OWNER |
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a single record in an existing table 1425029242 | |
1302759174 | https://github.com/simonw/datasette/issues/1863#issuecomment-1302759174 | https://api.github.com/repos/simonw/datasette/issues/1863 | IC_kwDOBm6k_c5NpocG | simonw 9599 | 2022-11-03T22:40:47Z | 2022-11-03T22:40:47Z | OWNER | I'm considering Pydantic for this, see: - https://github.com/simonw/datasette/issues/1882#issuecomment-1302716350 In particular the This would give me good validation. It would also, weirdly, give me the ability to output JSON schema. Maybe I could have this as the JSON schema for a row?
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Update a single record in an existing table 1425029242 | |
1302716350 | https://github.com/simonw/datasette/issues/1882#issuecomment-1302716350 | https://api.github.com/repos/simonw/datasette/issues/1882 | IC_kwDOBm6k_c5Npd-- | simonw 9599 | 2022-11-03T21:51:14Z | 2022-11-03T22:35:54Z | OWNER | Validating this JSON object is getting a tiny bit complex. I'm tempted to adopt https://pydantic-docs.helpmanual.io/ at this point. The
```python from pydantic import create_model d = {"strategy": {"name": "test_strat2", "periods": 10}} Strategy = create_model("Strategy", **d["strategy"]) print(Strategy.schema_json(indent=2))
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`/db/-/create` API for creating tables 1435294468 | |
1302721916 | https://github.com/simonw/datasette/issues/1882#issuecomment-1302721916 | https://api.github.com/repos/simonw/datasette/issues/1882 | IC_kwDOBm6k_c5NpfV8 | simonw 9599 | 2022-11-03T21:58:50Z | 2022-11-03T21:59:17Z | OWNER | Mocked up a quick HTML+JavaScript form for creating that JSON structure using some iteration against Copilot prompts: ```html /* JSON format: { "table": { "name": "my new table", "columns": [ { "name": "id", "type": "integer" }, { "name": "title", "type": "text" } ] "pk": "id" } } HTML form with Javascript for creating this JSON: */<form id="create-table-form"> <label for="table-name">Table name</label> <label for="table-pk">Primary key</label> <label for="column-name">Column name</label> <label for="column-type">Column type</label> <button type="button" id="add-column">Add column</button> Current columns: ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`/db/-/create` API for creating tables 1435294468 | |
1302715662 | https://github.com/simonw/datasette/issues/1882#issuecomment-1302715662 | https://api.github.com/repos/simonw/datasette/issues/1882 | IC_kwDOBm6k_c5Npd0O | simonw 9599 | 2022-11-03T21:50:27Z | 2022-11-03T21:50:27Z | OWNER | API design for this:
This matches my design for |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`/db/-/create` API for creating tables 1435294468 | |
1302679026 | https://github.com/simonw/datasette/issues/1843#issuecomment-1302679026 | https://api.github.com/repos/simonw/datasette/issues/1843 | IC_kwDOBm6k_c5NpU3y | simonw 9599 | 2022-11-03T21:22:42Z | 2022-11-03T21:22:42Z | OWNER | Docs for the new |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Intermittent "Too many open files" error running tests 1408757705 | |
1302678384 | https://github.com/simonw/datasette/issues/1843#issuecomment-1302678384 | https://api.github.com/repos/simonw/datasette/issues/1843 | IC_kwDOBm6k_c5NpUtw | simonw 9599 | 2022-11-03T21:21:59Z | 2022-11-03T21:21:59Z | OWNER | I added extra debug info to
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Intermittent "Too many open files" error running tests 1408757705 | |
1302634332 | https://github.com/simonw/datasette/issues/1843#issuecomment-1302634332 | https://api.github.com/repos/simonw/datasette/issues/1843 | IC_kwDOBm6k_c5NpJ9c | simonw 9599 | 2022-11-03T20:34:56Z | 2022-11-03T20:34:56Z | OWNER | Confirmed that calling I'm adding a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Intermittent "Too many open files" error running tests 1408757705 | |
1302574330 | https://github.com/simonw/datasette/issues/1843#issuecomment-1302574330 | https://api.github.com/repos/simonw/datasette/issues/1843 | IC_kwDOBm6k_c5No7T6 | simonw 9599 | 2022-11-03T19:30:22Z | 2022-11-03T19:30:22Z | OWNER | This is affecting me a lot at the moment, on my laptop (runs fine in CI). Here's a change to
``` tests/test_api.py ............E
item = <Function test_sql_time_limit>
/Users/simon/Dropbox/Development/datasette/tests/conftest.py:200: AssertionError
Which uses this fixture: Which calls this function: So now I'm suspicious that, even though the fixture is meant to be session scoped, the way I'm using |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Intermittent "Too many open files" error running tests 1408757705 | |
1301646670 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646670 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlY1O | simonw 9599 | 2022-11-03T05:11:26Z | 2022-11-03T05:11:26Z | OWNER | That still needs comprehensive tests before I land it. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301646493 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301646493 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlYyd | simonw 9599 | 2022-11-03T05:11:06Z | 2022-11-03T05:11:06Z | OWNER | Built a prototype of the above: ```diff diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 32b0c758..f68aa38f 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -6,8 +6,8 @@ import json import time -@hookimpl(tryfirst=True) -def permission_allowed(datasette, actor, action, resource): +@hookimpl(tryfirst=True, specname="permission_allowed") +def permission_allowed_default(datasette, actor, action, resource): async def inner(): if action in ( "permissions-debug", @@ -57,6 +57,44 @@ def permission_allowed(datasette, actor, action, resource): return inner +@hookimpl(specname="permission_allowed") +def permission_allowed_actor_restrictions(actor, action, resource): + if actor is None: + return None + r = actor.get("_r") + if not _r: + # No restrictions, so we have no opinion + return None + action_initials = "".join([word[0] for word in action.split("-")]) + # If _r is defined then we use those to further restrict the actor + # Crucially, we only use this to say NO (return False) - we never + # use it to return YES (True) because that might over-ride other + # restrictions placed on this actor + all_allowed = _r.get("a") + if all_allowed is not None: + assert isinstance(all_allowed, list) + if action_initials in all_allowed: + return None + # How about for the current database? + if action in ("view-database", "view-database-download", "execute-sql"): + database_allowed = _r.get("d", {}).get(resource) + if database_allowed is not None: + assert isinstance(database_allowed, list) + if action_initials in database_allowed: + return None + # Or the current table? That's any time the resource is (database, table) + if not isinstance(resource, str) and len(resource) == 2: + database, table = resource + table_allowed = _r.get("t", {}).get(database, {}).get(table) + # TODO: What should this do for canned queries? + if table_allowed is not None: + assert isinstance(table_allowed, list) + if action_initials in table_allowed: + return None + # This action is not specifically allowed, so reject it + return False + + @hookimpl def actor_from_request(datasette, request): prefix = "dstok" ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301639741 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639741 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXI9 | simonw 9599 | 2022-11-03T04:58:21Z | 2022-11-03T04:58:21Z | OWNER | The whole |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301639370 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301639370 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlXDK | simonw 9599 | 2022-11-03T04:57:21Z | 2022-11-03T04:57:21Z | OWNER | The plugin hook would be called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301638918 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638918 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlW8G | simonw 9599 | 2022-11-03T04:56:06Z | 2022-11-03T04:56:06Z | OWNER | I've also introduced a new concept of a permission abbreviation, which like the permission name needs to be globally unique. That's a problem for plugins - they might just be able to guarantee that their permission long-form name is unique among other plugins (through sensible naming conventions) but the thing where they declare a initial-letters-only abbreviation is far more risky. I think abbreviations are optional - they are provided for core permissions but plugins are advised not to use them. Also Datasette could check that the installed plugins do not provide conflicting permissions on startup and refuse to start if they do. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301638156 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301638156 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWwM | simonw 9599 | 2022-11-03T04:54:00Z | 2022-11-03T04:54:00Z | OWNER | If I have the permissions defined like this:
On the other hand though, plugins that introduce their own permissions - like https://datasette.io/plugins/datasette-edit-schema - will need a way to register those permissions with Datasette core. Probably another plugin hook. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301635906 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635906 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWNC | simonw 9599 | 2022-11-03T04:48:09Z | 2022-11-03T04:48:09Z | OWNER | I built this prototype on the http://127.0.0.1:8001/-/allow-debug page, which is open to anyone to visit. But... I just realized that using this tool can leak information - you can use it to guess the names of invisible databases and tables and run theoretical permission checks against them. Using the tool also pollutes the list of permission checks that show up on the root-anlo So.... I'm going to restrict the usage of this tool to users with access to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301635340 | https://github.com/simonw/datasette/issues/1881#issuecomment-1301635340 | https://api.github.com/repos/simonw/datasette/issues/1881 | IC_kwDOBm6k_c5NlWEM | simonw 9599 | 2022-11-03T04:46:41Z | 2022-11-03T04:46:41Z | OWNER | Built this prototype: In building it I realized I needed to know which permissions took a table, a database, both or neither. So I had to bake that into the code. Here's the prototype so far (which includes a prototype of the logic for the ```diff diff --git a/datasette/default_permissions.py b/datasette/default_permissions.py index 32b0c758..f68aa38f 100644 --- a/datasette/default_permissions.py +++ b/datasette/default_permissions.py @@ -6,8 +6,8 @@ import json import time -@hookimpl(tryfirst=True) -def permission_allowed(datasette, actor, action, resource): +@hookimpl(tryfirst=True, specname="permission_allowed") +def permission_allowed_default(datasette, actor, action, resource): async def inner(): if action in ( "permissions-debug", @@ -57,6 +57,44 @@ def permission_allowed(datasette, actor, action, resource): return inner +@hookimpl(specname="permission_allowed") +def permission_allowed_actor_restrictions(actor, action, resource): + if actor is None: + return None + r = actor.get("_r") + if not _r: + # No restrictions, so we have no opinion + return None + action_initials = "".join([word[0] for word in action.split("-")]) + # If _r is defined then we use those to further restrict the actor + # Crucially, we only use this to say NO (return False) - we never + # use it to return YES (True) because that might over-ride other + # restrictions placed on this actor + all_allowed = _r.get("a") + if all_allowed is not None: + assert isinstance(all_allowed, list) + if action_initials in all_allowed: + return None + # How about for the current database? + if action in ("view-database", "view-database-download", "execute-sql"): + database_allowed = _r.get("d", {}).get(resource) + if database_allowed is not None: + assert isinstance(database_allowed, list) + if action_initials in database_allowed: + return None + # Or the current table? That's any time the resource is (database, table) + if not isinstance(resource, str) and len(resource) == 2: + database, table = resource + table_allowed = _r.get("t", {}).get(database, {}).get(table) + # TODO: What should this do for canned queries? + if table_allowed is not None: + assert isinstance(table_allowed, list) + if action_initials in table_allowed: + return None + # This action is not specifically allowed, so reject it + return False + + @hookimpl def actor_from_request(datasette, request): prefix = "dstok" diff --git a/datasette/templates/allow_debug.html b/datasette/templates/allow_debug.html index 0f1b30f0..ae43f0f5 100644 --- a/datasette/templates/allow_debug.html +++ b/datasette/templates/allow_debug.html @@ -35,7 +35,7 @@ p.message-warning { Use this tool to try out different actor and allow combinations. See Defining permissions with "allow" blocks for documentation. -<form action="{{ urls.path('-/allow-debug') }}" method="get"> +<form action="{{ urls.path('-/allow-debug') }}" method="get" style="margin-bottom: 1em"> <label>Allow block</label> <textarea name="allow">{{ allow_input }}</textarea> @@ -55,4 +55,82 @@ p.message-warning {{% if result == "False" %} Result: deny {% endif %}+ Test permission check+ +This tool lets you simulate an actor and a permission check for that actor. + +<form action="{{ urls.path('-/allow-debug') }}" id="debug-post" method="post" style="margin-bottom: 1em"> + +
+
+ <label>Actor</label> + <textarea name="actor">{% if actor_input %}{{ actor_input }}{% else %}{"id": "root"}{% endif %}</textarea> +
+
+ <label>Permission check</label> +<label for="permission" style="display:block">Permission</label> + <select name="permission" id="permission"> + {% for permission in [ + "view-instance", + "view-database", + "view-database-download", + "view-table", + "view-query", + "insert-row", + "delete-row", + "drop-table", + "execute-sql", + "permissions-debug", + "debug-menu"] %} + <option value="{{ permission }}">{{ permission }}</option> + {% endfor %} + </select> + <label for="resource_1">Database name</label> +<label for="resource_2">Table or query name</label> +
+
+
+</form>
+
+<script>
+var rawPerms = {{ permissions|tojson }};
+var permissions = Object.fromEntries(rawPerms.map(([label, abbr, needs_resource_1, needs_resource_2, def]) => [label, {needs_resource_1, needs_resource_2, def}]))
+var permissionSelect = document.getElementById('permission');
+var resource1 = document.getElementById('resource_1');
+var resource2 = document.getElementById('resource_2');
+function updateResourceVisibility() {
+ var permission = permissionSelect.value;
+ var {needs_resource_1, needs_resource_2} = permissions[permission];
+ if (needs_resource_1) {
+ resource1.closest('p').style.display = 'block';
+ } else {
+ resource1.closest('p').style.display = 'none';
+ }
+ if (needs_resource_2) {
+ resource2.closest('p').style.display = 'block';
+ } else {
+ resource2.closest('p').style.display = 'none';
+ }
+}
+permissionSelect.addEventListener('change', updateResourceVisibility);
+updateResourceVisibility();
+
+// When #debug-post form is submitted, use fetch() to POST data
+var debugPost = document.getElementById('debug-post');
+debugPost.addEventListener('submit', function(ev) {
+ ev.preventDefault();
+ var formData = new FormData(debugPost);
+ console.log(formData);
+ fetch(debugPost.action, {
+ method: 'POST',
+ body: new URLSearchParams(formData),
+ }).then(function(response) {
+ return response.json();
+ }).then(function(data) {
+ alert(JSON.stringify(data, null, 4));
+ });
+});
+</script>
+ + {% endblock %} diff --git a/datasette/views/special.py b/datasette/views/special.py index 9922a621..d46fc280 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -1,6 +1,8 @@ import json +from datasette.permissions import PERMISSIONS from datasette.utils.asgi import Response, Forbidden from datasette.utils import actor_matches_allow, add_cors_headers +from datasette.permissions import PERMISSIONS from .base import BaseView import secrets import time @@ -138,9 +140,34 @@ class AllowDebugView(BaseView): "error": "\n\n".join(errors) if errors else "", "actor_input": actor_input, "allow_input": allow_input, + "permissions": PERMISSIONS, }, )
class MessagesDebugView(BaseView): name = "messages_debug" ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Tool for simulating permission checks against actors 1434094365 | |
1301594495 | https://github.com/simonw/datasette/issues/1855#issuecomment-1301594495 | https://api.github.com/repos/simonw/datasette/issues/1855 | IC_kwDOBm6k_c5NlMF_ | simonw 9599 | 2022-11-03T03:11:17Z | 2022-11-03T03:11:17Z | OWNER | Maybe the way to do this is through a new standard mechanism on the actor: a set of additional restrictions, e.g.:
The way this works is there's a default permission_allowed(datasette, actor, action, resource) hook which only consults these, and crucially just says NO if those rules do not match. In this way it would apply as an extra layer of permission rules over the defaults (which for this |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
`datasette create-token` ability to create tokens with a reduced set of permissions 1423336089 | |
1301043042 | https://github.com/simonw/datasette/issues/1880#issuecomment-1301043042 | https://api.github.com/repos/simonw/datasette/issues/1880 | IC_kwDOBm6k_c5NjFdi | amitkoth 525934 | 2022-11-02T18:20:14Z | 2022-11-02T18:20:14Z | NONE | Follow on question - is all memory use @simonw - for both datasette and SQLlite confined to the "query time" itself i.e. the memory use is relevant only to a particular transaction or query - and then subsequently released? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Datasette with many and large databases > Memory use 1433576351 | |
1299607082 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299607082 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ndm4q | simonw 9599 | 2022-11-02T05:45:31Z | 2022-11-02T05:45:31Z | OWNER | I'm going to add a link to the Datasette API docs for the current running version of Datasette, e.g. to https://docs.datasette.io/en/0.63/json_api.html |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299600257 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299600257 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdlOB | simonw 9599 | 2022-11-02T05:36:40Z | 2022-11-02T05:36:40Z | OWNER | The API Explorer should definitely link to the And it should probably go in the Datasette application menu? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299599461 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299599461 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdlBl | simonw 9599 | 2022-11-02T05:35:36Z | 2022-11-02T05:36:15Z | OWNER | Here's a slightly wild idea: what if there was a button on Only reason I don't want to show these to everyone is that I don't think this is a very user-friendly feature: if you don't know what an API is I don't want to expose you to it unnecessarily. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299598570 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299598570 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ndkzq | simonw 9599 | 2022-11-02T05:34:28Z | 2022-11-02T05:34:28Z | OWNER | This is pretty useful now. Two features I still want to add:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299597066 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299597066 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NdkcK | simonw 9599 | 2022-11-02T05:32:22Z | 2022-11-02T05:32:22Z | OWNER | Demo of the latest API explorer: |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299388341 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299388341 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5Ncxe1 | simonw 9599 | 2022-11-02T00:24:28Z | 2022-11-02T00:25:00Z | OWNER | I want JSON syntax highlighting. https://github.com/luyilin/json-format-highlight is an MIT licensed tiny highlighter that looks decent for this. https://unpkg.com/json-format-highlight@1.0.1/dist/json-format-highlight.js |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299349741 | https://github.com/simonw/datasette/issues/1871#issuecomment-1299349741 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NcoDt | simonw 9599 | 2022-11-01T23:22:55Z | 2022-11-01T23:22:55Z | OWNER | It's weird that the API explorer only lets you explore POST APIs. It should probably also let you explore GET APIs, or be renamed. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1299098458 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299098458 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbqta | simonw 9599 | 2022-11-01T20:27:40Z | 2022-11-01T20:33:52Z | OWNER | https://github.com/simonw/datasette-x-forwarded-host/blob/main/datasette_x_forwarded_host/init.py could happen in core controlled by:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299102108 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299102108 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbrmc | simonw 9599 | 2022-11-01T20:30:54Z | 2022-11-01T20:33:06Z | OWNER | One idea: add a |
{ "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299102755 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299102755 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nbrwj | simonw 9599 | 2022-11-01T20:31:37Z | 2022-11-01T20:31:37Z | OWNER | And some JavaScript that can spot if Datasette thinks it is being served over HTTP when it's actually being served over HTTPS. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299096850 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299096850 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5NbqUS | simonw 9599 | 2022-11-01T20:26:12Z | 2022-11-01T20:26:12Z | OWNER | The other relevant plugin here is https://datasette.io/plugins/datasette-x-forwarded-host Maybe that should be rolled into core too? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299090678 | https://github.com/simonw/datasette/issues/1879#issuecomment-1299090678 | https://api.github.com/repos/simonw/datasette/issues/1879 | IC_kwDOBm6k_c5Nboz2 | simonw 9599 | 2022-11-01T20:20:28Z | 2022-11-01T20:20:28Z | OWNER | My first step in debugging these is to install https://datasette.io/plugins/datasette-debug-asgi - but now I'm thinking maybe something like that should be part of core. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make it easier to fix URL proxy problems 1432037325 | |
1299073433 | https://github.com/simonw/datasette/issues/1862#issuecomment-1299073433 | https://api.github.com/repos/simonw/datasette/issues/1862 | IC_kwDOBm6k_c5NbkmZ | simonw 9599 | 2022-11-01T20:04:31Z | 2022-11-01T20:04:31Z | OWNER | It really feels like this should be accompanied by a https://sqlite-utils.datasette.io/en/stable/cli.html#cli-create-table |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Create a new table from one or more records, `sqlite-utils` style 1425011030 | |
1299071456 | https://github.com/simonw/datasette/issues/1878#issuecomment-1299071456 | https://api.github.com/repos/simonw/datasette/issues/1878 | IC_kwDOBm6k_c5NbkHg | simonw 9599 | 2022-11-01T20:02:43Z | 2022-11-01T20:02:43Z | OWNER | Note that "update" is partially covered by the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
/db/table/-/upsert API 1432013704 | |
1298919552 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298919552 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na_CA | simonw 9599 | 2022-11-01T18:11:27Z | 2022-11-01T18:11:27Z | OWNER | I forgot to document
I think my validation logic here will get caught out by the fact that |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298905135 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298905135 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na7gv | simonw 9599 | 2022-11-01T17:59:59Z | 2022-11-01T17:59:59Z | OWNER | It's a bit surprising that you can send Three options:
I'm picking 3 - I'm going to change it to be called |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298885451 | https://github.com/simonw/datasette/issues/1873#issuecomment-1298885451 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5Na2tL | simonw 9599 | 2022-11-01T17:42:20Z | 2022-11-01T17:42:20Z | OWNER | Design decision:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1298879701 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1298879701 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5Na1TV | simonw 9599 | 2022-11-01T17:37:13Z | 2022-11-01T17:37:13Z | OWNER | The question I was originally trying to answer here was this: how many rows were actually inserted by that call to I don't know that So I think if people need |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1298877872 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1298877872 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5Na02w | simonw 9599 | 2022-11-01T17:35:30Z | 2022-11-01T17:35:30Z | OWNER | This may not make sense. First, So I tried this prototype:
+After executing a query the db.execute(sql, params) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index a06f4b7..c19c2dd 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -294,6 +294,8 @@ class Database:
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1298856054 | https://github.com/simonw/datasette/issues/1876#issuecomment-1298856054 | https://api.github.com/repos/simonw/datasette/issues/1876 | IC_kwDOBm6k_c5Navh2 | simonw 9599 | 2022-11-01T17:16:01Z | 2022-11-01T17:16:01Z | OWNER |
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query should wrap on SQL interrupted screen 1431786951 | |
1298854321 | https://github.com/simonw/datasette/issues/1876#issuecomment-1298854321 | https://api.github.com/repos/simonw/datasette/issues/1876 | IC_kwDOBm6k_c5NavGx | simonw 9599 | 2022-11-01T17:14:33Z | 2022-11-01T17:14:33Z | OWNER | I could use a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SQL query should wrap on SQL interrupted screen 1431786951 | |
1297859539 | https://github.com/simonw/sqlite-utils/issues/507#issuecomment-1297859539 | https://api.github.com/repos/simonw/sqlite-utils/issues/507 | IC_kwDOCGYnMM5NW8PT | chapmanjacobd 7908073 | 2022-11-01T00:40:16Z | 2022-11-01T00:40:16Z | CONTRIBUTOR | Ideally people could fix their data if they run into this issue. If you are using filenames try convmv
maybe this script will also help: ```py import argparse, shutil from pathlib import Path import ftfy from xklb import utils from xklb.utils import log def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() parser.add_argument("paths", nargs='*') parser.add_argument("--verbose", "-v", action="count", default=0) args = parser.parse_args()
def rename_invalid_paths() -> None: args = parse_args()
if name == "main": rename_invalid_paths() ``` |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
conn.execute: UnicodeEncodeError: 'utf-8' codec can't encode character 1430325103 | |
1297754631 | https://github.com/simonw/sqlite-utils/pull/508#issuecomment-1297754631 | https://api.github.com/repos/simonw/sqlite-utils/issues/508 | IC_kwDOCGYnMM5NWioH | codecov[bot] 22429695 | 2022-10-31T22:14:48Z | 2022-10-31T22:53:59Z | NONE | Codecov ReportBase: 96.25% // Head: 96.09% // Decreases project coverage by
Additional details and impacted files```diff @@ Coverage Diff @@ ## main #508 +/- ## ========================================== - Coverage 96.25% 96.09% -0.16% ========================================== Files 4 4 Lines 2401 2407 +6 ========================================== + Hits 2311 2313 +2 - Misses 90 94 +4 ``` | [Impacted Files](https://codecov.io/gh/simonw/sqlite-utils/pull/508?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [sqlite\_utils/db.py](https://codecov.io/gh/simonw/sqlite-utils/pull/508/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `96.79% <63.63%> (-0.30%)` | :arrow_down: | Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison):umbrella: View full report at Codecov. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Allow surrogates in parameters 1430563092 | |
1297703307 | https://github.com/simonw/sqlite-utils/issues/448#issuecomment-1297703307 | https://api.github.com/repos/simonw/sqlite-utils/issues/448 | IC_kwDOCGYnMM5NWWGL | mcarpenter 167893 | 2022-10-31T21:23:51Z | 2022-10-31T21:27:32Z | CONTRIBUTOR | The Windows aspect is a red herring: OP's sample above produces the same error on Linux. (Though I don't know what's going on with the CI). The same error can also be obtained by passing an The fix for my case is easy: open the file in mode Minimal test case (derived from utils.py): ``` python import io from typing import cast fp = io.StringIO("id,name\n1,Cleo") # errorfp = io.BytesIO(bytes("id,name\n1,Cleo", encoding='utf-8')) # okay
reader = io.BufferedReader(cast(io.RawIOBase, fp))
reader.peek(1) # exception thrown here
Some thoughts on testing binary-ness of |
{ "total_count": 2, "+1": 2, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Reading rows from a file => AttributeError: '_io.StringIO' object has no attribute 'readinto' 1279144769 | |
1297201971 | https://github.com/dogsheep/twitter-to-sqlite/issues/61#issuecomment-1297201971 | https://api.github.com/repos/dogsheep/twitter-to-sqlite/issues/61 | IC_kwDODEm0Qs5NUbsz | Profpatsch 3153638 | 2022-10-31T14:47:58Z | 2022-10-31T14:47:58Z | NONE | There’s also a limit of 3200 tweets. I wonder if that can be circumvented somehow. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Data Pull fails for "Essential" level access to the Twitter API (for Documentation) 1077560091 | |
1296403316 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296403316 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRYt0 | simonw 9599 | 2022-10-31T00:39:43Z | 2022-10-31T00:39:43Z | OWNER | It looks like SQLite has features for this already: https://www.sqlite.org/foreignkeys.html#fk_actions
On that basis, I'm not going to implement anything additional in the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296402071 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296402071 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRYaX | simonw 9599 | 2022-10-31T00:37:09Z | 2022-10-31T00:37:09Z | OWNER | I need to think about what happens if you delete a row that is the target of a foreign key from another row. https://www.sqlite.org/foreignkeys.html#fk_enable shows that SQLite will only actively enforce these relationships (e.g. throw an error if you try to delete a row that is referenced by another row) if you first run
I don't actually believe that the SQLite maintainers will ever make that the default though. Datasette doesn't turn these on at the moment, but it could be turned on by a |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296375536 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296375536 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRR7w | simonw 9599 | 2022-10-30T23:17:11Z | 2022-10-30T23:17:11Z | OWNER | I'm a bit nervous about calling |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296375310 | https://github.com/simonw/datasette/issues/1864#issuecomment-1296375310 | https://api.github.com/repos/simonw/datasette/issues/1864 | IC_kwDOBm6k_c5NRR4O | simonw 9599 | 2022-10-30T23:16:19Z | 2022-10-30T23:16:19Z | OWNER | Still needs tests that cover compound primary keys and rowid tables. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Delete a single record from an existing table 1425029275 | |
1296363981 | https://github.com/simonw/datasette/issues/1874#issuecomment-1296363981 | https://api.github.com/repos/simonw/datasette/issues/1874 | IC_kwDOBm6k_c5NRPHN | simonw 9599 | 2022-10-30T22:19:47Z | 2022-10-30T22:19:47Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to drop a table 1429030341 | ||
1296358636 | https://github.com/simonw/sqlite-utils/issues/506#issuecomment-1296358636 | https://api.github.com/repos/simonw/sqlite-utils/issues/506 | IC_kwDOCGYnMM5NRNzs | simonw 9599 | 2022-10-30T21:52:11Z | 2022-10-30T21:52:11Z | OWNER | This could work in a similar way to |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Make `cursor.rowcount` accessible (wontfix) 1429029604 | |
1296343716 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343716 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKKk | simonw 9599 | 2022-10-30T20:24:55Z | 2022-10-30T20:24:55Z | OWNER | I think the key feature I need here is going to be the equivalent of |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343317 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343317 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKEV | simonw 9599 | 2022-10-30T20:22:40Z | 2022-10-30T20:22:40Z | OWNER | So maybe they're not actually worth worrying about separately, because they are guaranteed to have a primary key set. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343173 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343173 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRKCF | simonw 9599 | 2022-10-30T20:21:54Z | 2022-10-30T20:22:20Z | OWNER | One last case to consider: https://www.sqlite.org/withoutrowid.html
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296343014 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296343014 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJ_m | simonw 9599 | 2022-10-30T20:21:01Z | 2022-10-30T20:21:01Z | OWNER | Actually, for simplicity I'm going to say that you can always set the primary key, even for auto-incrementing primary key columns... but you cannot set it on pure |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296342814 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296342814 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJ8e | simonw 9599 | 2022-10-30T20:20:05Z | 2022-10-30T20:20:05Z | OWNER | Some notes on what Datasette does already https://latest.datasette.io/fixtures/tags.json?_shape=array returns:
https://latest.datasette.io/fixtures/binary_data.json?_shape=array
https://latest.datasette.io/fixtures/simple_primary_key.json?_shape=array
https://latest.datasette.io/fixtures/compound_primary_key.json?_shape=array
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296341469 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296341469 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJnd | simonw 9599 | 2022-10-30T20:13:50Z | 2022-10-30T20:13:50Z | OWNER | I checked and SQLite itself does allow you to set the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296341055 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296341055 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NRJg_ | simonw 9599 | 2022-10-30T20:11:47Z | 2022-10-30T20:12:30Z | OWNER | If a table has an auto-incrementing primary key, should you be allowed to insert records with an explicit key into it? I'm torn on this one. It's something you can do with direct database access, but it's something I very rarely want to do. I'm inclined to disallow it and say that if you want that you can get it using a writable canned query instead. Likewise, I'm not going to provide a way to set the |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | |
1296339386 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296339386 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NRJG6 | simonw 9599 | 2022-10-30T20:03:04Z | 2022-10-30T20:03:04Z | OWNER | I do need to skip CSRF for these API calls. I'm going to start out by doing that using the
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296339205 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296339205 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NRJEF | simonw 9599 | 2022-10-30T20:02:05Z | 2022-10-30T20:02:05Z | OWNER | Realized the API explorer doesn't need the API key piece at all - it can work with standard cookie-based auth. This also reflects how most plugins are likely to use this API, where they'll be adding JavaScript that uses |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296131872 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296131872 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQWcg | simonw 9599 | 2022-10-30T06:27:56Z | 2022-10-30T06:27:56Z | OWNER | Initial prototype API explorer is now live at https://latest-1-0-dev.datasette.io/-/api |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296131681 | https://github.com/simonw/datasette/issues/1873#issuecomment-1296131681 | https://api.github.com/repos/simonw/datasette/issues/1873 | IC_kwDOBm6k_c5NQWZh | simonw 9599 | 2022-10-30T06:27:12Z | 2022-10-30T06:27:12Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Ensure insert API has good tests for rowid and compound primark key tables 1428630253 | ||
1296131343 | https://github.com/simonw/datasette/issues/1872#issuecomment-1296131343 | https://api.github.com/repos/simonw/datasette/issues/1872 | IC_kwDOBm6k_c5NQWUP | simonw 9599 | 2022-10-30T06:26:01Z | 2022-10-30T06:26:01Z | OWNER | Good spot fixing that! Sorry about this - it was a change in Datasette 0.63 which should have been better called out. My goal for Datasette 1.0 (which I aim to have out by the end of the year) is to introduce a formal process for avoiding problems like this, with very clear documentation when something like this might happen. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SITE-BUSTING ERROR: "render_template() called before await ds.invoke_startup()" 1428560020 | |
1296130073 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296130073 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQWAZ | simonw 9599 | 2022-10-30T06:20:56Z | 2022-10-30T06:20:56Z | OWNER | That initial prototype looks like this: It currently shows the returned JSON from the API in an |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296126389 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296126389 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQVG1 | simonw 9599 | 2022-10-30T06:04:48Z | 2022-10-30T06:04:48Z | OWNER | This is even more important now I have pushed: - #1866 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296114136 | https://github.com/simonw/datasette/issues/1871#issuecomment-1296114136 | https://api.github.com/repos/simonw/datasette/issues/1871 | IC_kwDOBm6k_c5NQSHY | simonw 9599 | 2022-10-30T05:15:40Z | 2022-10-30T05:15:40Z | OWNER | Host it at It's an input box with a path in and a textarea you can put JSON in, plus a submit button to post the request. It lists the API endpoints you can use - click on a link to populate the form field plus a example. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API explorer tool 1427293909 | |
1296080804 | https://github.com/simonw/datasette/issues/1872#issuecomment-1296080804 | https://api.github.com/repos/simonw/datasette/issues/1872 | IC_kwDOBm6k_c5NQJ-k | mroswell 192568 | 2022-10-30T03:06:32Z | 2022-10-30T03:06:32Z | CONTRIBUTOR | I updated datasette-publish-vercel to 0.14.2 in requirements.txt And the site is back up! Is there a way that we can get some sort of notice when something like this will have critical impact on website function? |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SITE-BUSTING ERROR: "render_template() called before await ds.invoke_startup()" 1428560020 | |
1296076803 | https://github.com/simonw/datasette/issues/1872#issuecomment-1296076803 | https://api.github.com/repos/simonw/datasette/issues/1872 | IC_kwDOBm6k_c5NQJAD | mroswell 192568 | 2022-10-30T02:50:34Z | 2022-10-30T02:50:34Z | CONTRIBUTOR | should this issue be under https://github.com/simonw/datasette-publish-vercel/issues ? Perhaps I just need to update: datasette-publish-vercel==0.11 in requirements.txt? I'll try that and see what happens... |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
SITE-BUSTING ERROR: "render_template() called before await ds.invoke_startup()" 1428560020 | |
1295667649 | https://github.com/simonw/datasette/pull/1870#issuecomment-1295667649 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NOlHB | fgregg 536941 | 2022-10-29T00:52:43Z | 2022-10-29T00:53:43Z | CONTRIBUTOR |
Somehow, I don't understand how that happens. it kind of feels like a bug in sqlite, but i can't quite follow the sqlite code. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1295660092 | https://github.com/simonw/datasette/pull/1870#issuecomment-1295660092 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NOjQ8 | simonw 9599 | 2022-10-29T00:25:26Z | 2022-10-29T00:25:26Z | OWNER | Saw your comment here too: https://github.com/simonw/datasette/issues/1480#issuecomment-1271101072
So maybe we need a special case for containers that are intended to be run using Docker - the ones produced by Maybe a I should run some benchmarks to figure out if |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1295657771 | https://github.com/simonw/datasette/pull/1870#issuecomment-1295657771 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NOisr | simonw 9599 | 2022-10-29T00:19:03Z | 2022-10-29T00:19:03Z | OWNER | Just saw your comment here: https://github.com/simonw/datasette/issues/1836#issuecomment-1272357976
I don't understand this. My mental model of how Docker works is that the image itself is created using Are you saying that I can build a container, but then when I run it and it does |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1295200988 | https://github.com/simonw/datasette/issues/1866#issuecomment-1295200988 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NMzLc | simonw 9599 | 2022-10-28T16:29:55Z | 2022-10-28T16:29:55Z | OWNER | I wonder if there's something clever I could do here within a transaction? Start a transaction. Write out a temporary in-memory table with all of the existing primary keys in the table. Run the bulk insert. Then run I don't think that's going to work well for large tables. I'm going to go with not returning inserted rows by default, unless you pass a special option requesting that. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294408928 | https://github.com/simonw/sqlite-utils/issues/496#issuecomment-1294408928 | https://api.github.com/repos/simonw/sqlite-utils/issues/496 | IC_kwDOCGYnMM5NJxzg | justmars 39538958 | 2022-10-28T03:36:56Z | 2022-10-28T03:37:50Z | NONE | With respect to the typing of Table class itself, my interim solution:
With respect to @chapmanjacobd concern on the
|
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
devrel/python api: Pylance type hinting 1393202060 | |
1294316640 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294316640 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJbRg | simonw 9599 | 2022-10-28T01:51:40Z | 2022-10-28T01:51:40Z | OWNER | This needs to support the following: - Rows do not include a primary key - one is assigned by the database - Rows provide their own primary key, any clashes are errors - Rows provide their own primary key, clashes are silently ignored - Rows provide their own primary key, replacing any existing records |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294306071 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294306071 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJYsX | simonw 9599 | 2022-10-28T01:37:14Z | 2022-10-28T01:37:59Z | OWNER | Quick crude benchmark: ```python import sqlite3 db = sqlite3.connect(":memory:") def create_table(db, name): db.execute(f"create table {name} (id integer primary key, title text)") create_table(db, "single") create_table(db, "multi") create_table(db, "bulk") def insert_singles(titles): inserted = [] for title in titles: cursor = db.execute(f"insert into single (title) values (?)", [title]) inserted.append((cursor.lastrowid, title)) return inserted def insert_many(titles): db.executemany(f"insert into multi (title) values (?)", ((t,) for t in titles)) def insert_bulk(titles): db.execute("insert into bulk (title) values {}".format( ", ".join("(?)" for _ in titles) ), titles) titles = ["title {}".format(i) for i in range(1, 10001)]
In [13]: %timeit insert_many(titles) 12 ms ± 520 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [12]: %timeit insert_bulk(titles) 2.59 ms ± 25 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) ``` So the bulk insert really is a lot faster - 3ms compared to 24ms for single inserts, so ~8x faster. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294296767 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294296767 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJWa_ | simonw 9599 | 2022-10-28T01:22:25Z | 2022-10-28T01:23:09Z | OWNER | Nasty catch on this one: I wanted to return the IDs of the freshly inserted rows. But... the SQLite itself added a Two options then:
That third option might be the way to go here. I should benchmark first to figure out how much of a difference this actually makes. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294285471 | https://github.com/simonw/datasette/pull/1870#issuecomment-1294285471 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NJTqf | fgregg 536941 | 2022-10-28T01:06:03Z | 2022-10-28T01:06:03Z | CONTRIBUTOR | as far as i can tell, this is where the "immutable" argument is used in sqlite:
so it does set the read only flag, but then has a goto. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1294282263 | https://github.com/simonw/datasette/issues/1866#issuecomment-1294282263 | https://api.github.com/repos/simonw/datasette/issues/1866 | IC_kwDOBm6k_c5NJS4X | simonw 9599 | 2022-10-28T01:00:42Z | 2022-10-28T01:00:42Z | OWNER | I'm going to set the limit at 1,000 rows inserted at a time. I'll make this configurable using a new |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API for bulk inserting records into a table 1426001541 | |
1294281451 | https://github.com/simonw/datasette/issues/1851#issuecomment-1294281451 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5NJSrr | simonw 9599 | 2022-10-28T00:59:25Z | 2022-10-28T00:59:25Z | OWNER | I'm going to use this endpoint for bulk inserts too, so I'm closing this issue and continuing the work here: - #1866 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294238862 | https://github.com/simonw/datasette/pull/1870#issuecomment-1294238862 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NJISO | codecov[bot] 22429695 | 2022-10-27T23:44:25Z | 2022-10-27T23:44:25Z | NONE | Codecov ReportBase: 92.55% // Head: 92.55% // No change to project coverage :thumbsup:
Additional details and impacted files```diff @@ Coverage Diff @@ ## main #1870 +/- ## ======================================= Coverage 92.55% 92.55% ======================================= Files 35 35 Lines 4432 4432 ======================================= Hits 4102 4102 Misses 330 330 ``` | [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1870?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | | |---|---|---| | [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1870/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.30% <ø> (ø)` | | Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison):umbrella: View full report at Codecov. |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1294237783 | https://github.com/simonw/datasette/pull/1870#issuecomment-1294237783 | https://api.github.com/repos/simonw/datasette/issues/1870 | IC_kwDOBm6k_c5NJIBX | fgregg 536941 | 2022-10-27T23:42:18Z | 2022-10-27T23:42:18Z | CONTRIBUTOR | Relevant sqlite forum thread: https://www.sqlite.org/forum/forumpost/02f7bda329f41e30451472421cf9ce7f715b768ce3db02797db1768e47950d48 |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
don't use immutable=1, only mode=ro 1426379903 | |
1289712350 | https://github.com/simonw/datasette/issues/1851#issuecomment-1289712350 | https://api.github.com/repos/simonw/datasette/issues/1851 | IC_kwDOBm6k_c5M33Le | simonw 9599 | 2022-10-24T22:28:39Z | 2022-10-27T23:18:48Z | OWNER | API design: (**UPDATE: this was later changed to POST /db/table/-/insert)
I decided to use |
{ "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
API to insert a single record into an existing table 1421544654 | |
1294181485 | https://github.com/simonw/datasette/issues/1869#issuecomment-1294181485 | https://api.github.com/repos/simonw/datasette/issues/1869 | IC_kwDOBm6k_c5NI6Rt | simonw 9599 | 2022-10-27T22:24:37Z | 2022-10-27T22:24:37Z | OWNER | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
Release 0.63 1426253476 |
Advanced export
JSON shape: default, array, newline-delimited, object
CREATE TABLE [issue_comments] ( [html_url] TEXT, [issue_url] TEXT, [id] INTEGER PRIMARY KEY, [node_id] TEXT, [user] INTEGER REFERENCES [users]([id]), [created_at] TEXT, [updated_at] TEXT, [author_association] TEXT, [body] TEXT, [reactions] TEXT, [issue] INTEGER REFERENCES [issues]([id]) , [performed_via_github_app] TEXT); CREATE INDEX [idx_issue_comments_issue] ON [issue_comments] ([issue]); CREATE INDEX [idx_issue_comments_user] ON [issue_comments] ([user]);
issue >1000