home / github

Menu
  • Search all tables
  • GraphQL API

issue_comments

Table actions
  • GraphQL API for issue_comments

11 rows where author_association = "OWNER", issue = 564833696 and user = 9599 sorted by updated_at descending

✖
✖
✖
✖

✎ View and edit SQL

This data as json, CSV (advanced)

user 1

  • simonw · 11 ✖

issue 1

  • Prototoype for Datasette on PostgreSQL · 11 ✖

author_association 1

  • OWNER · 11 ✖
id html_url issue_url node_id user created_at updated_at ▲ author_association body reactions issue performed_via_github_app
849022714 https://github.com/simonw/datasette/issues/670#issuecomment-849022714 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDg0OTAyMjcxNA== simonw 9599 2021-05-26T18:33:47Z 2021-05-26T18:33:58Z OWNER

Worth mentioning here: I've been doing a tun of research around running Datasette-like functionality against PostgreSQL in my https://github.com/simonw/django-sql-dashboard project - which will definitely inform the Datasette implementation.

{
    "total_count": 3,
    "+1": 3,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
797158641 https://github.com/simonw/datasette/issues/670#issuecomment-797158641 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDc5NzE1ODY0MQ== simonw 9599 2021-03-12T00:59:49Z 2021-03-12T00:59:49Z OWNER

Challenge: what's the equivalent for PostgreSQL of opening a database in read only mode? Will I have to talk users through creating read only credentials?

It looks like the answer to this is yes - I'll need users to setup read-only credentials. Here's a TIL about that: https://til.simonwillison.net/postgresql/read-only-postgresql-user

{
    "total_count": 1,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 1,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585962849 https://github.com/simonw/datasette/issues/670#issuecomment-585962849 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTk2Mjg0OQ== simonw 9599 2020-02-13T20:44:18Z 2020-02-13T20:46:53Z OWNER

Got the database page working! It lists tables, their columns and their row count.

Got the table page partially working! It can list rows.

It can't apply filters yet (because PostgreSQL $1 parameters differ from SQLite :blah parameters) and faceting doesn't work because PostgreSQL requires that subqueries have an alias: subquery in FROM must have an alias HINT: For example, FROM (SELECT ...) [AS] foo. Still a pretty promising start though!

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585903240 https://github.com/simonw/datasette/issues/670#issuecomment-585903240 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTkwMzI0MA== simonw 9599 2020-02-13T18:28:42Z 2020-02-13T18:29:14Z OWNER

Challenge: what's the equivalent for PostgreSQL of opening a database in read only mode? Will I have to talk users through creating read only credentials? Can I do this at runtime somehow? Can I detect if the connection has write permission and disable the arbitrary query feature?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585885812 https://github.com/simonw/datasette/issues/670#issuecomment-585885812 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg4NTgxMg== simonw 9599 2020-02-13T17:49:33Z 2020-02-13T17:49:33Z OWNER

In [12]: await conn.fetch("""SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type ...: FROM pg_index i ...: JOIN pg_attribute a ON a.attrelid = i.indrelid ...: AND a.attnum = ANY(i.indkey) ...: WHERE i.indrelid = 'blog_blogmark'::regclass ...: AND i.indisprimary;""") Out[12]: [<Record attname='id' data_type='integer'>]

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585885242 https://github.com/simonw/datasette/issues/670#issuecomment-585885242 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg4NTI0Mg== simonw 9599 2020-02-13T17:48:27Z 2020-02-13T17:48:27Z OWNER

Finding out the primary keys for a table: https://wiki.postgresql.org/wiki/Retrieve_primary_key_columns

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585883109 https://github.com/simonw/datasette/issues/670#issuecomment-585883109 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg4MzEwOQ== simonw 9599 2020-02-13T17:44:08Z 2020-02-13T17:44:08Z OWNER

Introspecting columns in PostgreSQL: In [3]: sql = """SELECT * ...: FROM information_schema.columns ...: WHERE table_schema = 'public' ...: AND table_name = 'blog_blogmark' ...: ;""" Each column looks like this: pythton {'table_catalog': 'simonwillisonblog', 'table_schema': 'public', 'table_name': 'blog_blogmark', 'column_name': 'id', 'ordinal_position': 1, 'column_default': "nextval('blog_blogmark_id_seq'::regclass)", 'is_nullable': 'NO', 'data_type': 'integer', 'character_maximum_length': None, 'character_octet_length': None, 'numeric_precision': 32, 'numeric_precision_radix': 2, 'numeric_scale': 0, 'datetime_precision': None, 'interval_type': None, 'interval_precision': None, 'character_set_catalog': None, 'character_set_schema': None, 'character_set_name': None, 'collation_catalog': None, 'collation_schema': None, 'collation_name': None, 'domain_catalog': None, 'domain_schema': None, 'domain_name': None, 'udt_catalog': 'simonwillisonblog', 'udt_schema': 'pg_catalog', 'udt_name': 'int4', 'scope_catalog': None, 'scope_schema': None, 'scope_name': None, 'maximum_cardinality': None, 'dtd_identifier': '1', 'is_self_referencing': 'NO', 'is_identity': 'NO', 'identity_generation': None, 'identity_start': None, 'identity_increment': None, 'identity_maximum': None, 'identity_minimum': None, 'identity_cycle': 'NO', 'is_generated': 'NEVER', 'generation_expression': None, 'is_updatable': 'YES'}

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585874699 https://github.com/simonw/datasette/issues/670#issuecomment-585874699 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg3NDY5OQ== simonw 9599 2020-02-13T17:26:58Z 2020-02-13T17:27:13Z OWNER

First page to get working: the database view page, which shows a list of tables.

In the code this is entirely implemented with calls to the Database class, which is a good starting point - I can drop in a new version of that class that talks to PostgreSQL instead:

https://github.com/simonw/datasette/blob/0091dfe3e5a3db94af8881038d3f1b8312bb857d/datasette/views/database.py#L25-L66

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585873401 https://github.com/simonw/datasette/issues/670#issuecomment-585873401 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg3MzQwMQ== simonw 9599 2020-02-13T17:24:38Z 2020-02-13T17:24:38Z OWNER

The biggest difference between the two will be around introspection. I searched the codebase for potential introspection queries, defined as select ... from sqlite_master and pragma ... statements.

  • 7 results for sqlite_master in database.py
  • 3 results in utils/init.py
  • (Ignoring the 4 in inspect.py)
  • 1 result for “pragma table_info” in app.py
  • 2 in utils/init.py
  • 2 results for “pragma foreign_key_list” in utils/init.py
{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585872538 https://github.com/simonw/datasette/issues/670#issuecomment-585872538 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg3MjUzOA== simonw 9599 2020-02-13T17:22:54Z 2020-02-13T17:22:54Z OWNER

A couple of things I'd like to support: - The same datasette instance can have both PostgreSQL and SQLite databases attached to it, and both types will be listed on the homepage. - The full test suite runs against both SQLite and PostgreSQL, with as few changes as possible (maybe a few skipIf() decorators for features not available on both). Probably easiest do do this with some kind of flag - e.g. pytest --database=sqlite v.s. pytest --database=postgresql

I can implement that with this in conftest.py: python def pytest_addoption(parser): parser.addoption("--database", action="store", default="sqlite") See https://stackoverflow.com/questions/40880259/how-to-pass-arguments-in-pytest-by-command-line

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  
585870836 https://github.com/simonw/datasette/issues/670#issuecomment-585870836 https://api.github.com/repos/simonw/datasette/issues/670 MDEyOklzc3VlQ29tbWVudDU4NTg3MDgzNg== simonw 9599 2020-02-13T17:19:23Z 2020-02-13T17:19:37Z OWNER

I'm excited about https://github.com/MagicStack/asyncpg for this - it's a true async PostgreSQL library (my SQLite queries run in a threadpool right now) with extremely impressive performance benchmarks, from the team behind uvloop.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
Prototoype for Datasette on PostgreSQL 564833696  

Advanced export

JSON shape: default, array, newline-delimited, object

CSV options:

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]);
Powered by Datasette · Queries took 1562.584ms · About: github-to-sqlite
  • Sort ascending
  • Sort descending
  • Facet by this
  • Hide this column
  • Show all columns
  • Show not-blank rows