Include foreign key info in inspect() output

Refs #85
pull/107/head^2
Simon Willison 2017-11-15 17:34:32 -08:00
rodzic 5d8084a285
commit a4af532a31
2 zmienionych plików z 43 dodań i 7 usunięć

Wyświetl plik

@ -16,14 +16,15 @@ import hashlib
import time import time
from .utils import ( from .utils import (
build_where_clauses, build_where_clauses,
compound_pks_from_path,
CustomJSONEncoder, CustomJSONEncoder,
escape_css_string, escape_css_string,
escape_sqlite_table_name, escape_sqlite_table_name,
get_all_foreign_keys,
InvalidSql, InvalidSql,
path_from_row_pks, path_from_row_pks,
path_with_added_args, path_with_added_args,
path_with_ext, path_with_ext,
compound_pks_from_path,
sqlite_timelimit, sqlite_timelimit,
validate_sql_select, validate_sql_select,
) )
@ -253,12 +254,12 @@ class IndexView(HTTPMethodView):
'path': '{}-{}'.format(key, info['hash'][:7]), 'path': '{}-{}'.format(key, info['hash'][:7]),
'tables_truncated': sorted( 'tables_truncated': sorted(
info['tables'].items(), info['tables'].items(),
key=lambda p: p[1], key=lambda p: p[1]['count'],
reverse=True reverse=True
)[:5], )[:5],
'tables_count': len(info['tables'].items()), 'tables_count': len(info['tables'].items()),
'tables_more': len(info['tables'].items()) > 5, 'tables_more': len(info['tables'].items()) > 5,
'table_rows': sum(info['tables'].values()), 'table_rows': sum([t['count'] for t in info['tables'].values()]),
} }
databases.append(database) databases.append(database)
if as_json: if as_json:
@ -294,7 +295,7 @@ class DatabaseView(BaseView):
return await self.custom_sql(request, name, hash) return await self.custom_sql(request, name, hash)
tables = [] tables = []
table_inspect = self.ds.inspect()[name]['tables'] table_inspect = self.ds.inspect()[name]['tables']
for table_name, table_rows in table_inspect.items(): for table_name, info in table_inspect.items():
rows = await self.execute( rows = await self.execute(
name, name,
'PRAGMA table_info([{}]);'.format(table_name) 'PRAGMA table_info([{}]);'.format(table_name)
@ -302,7 +303,7 @@ class DatabaseView(BaseView):
tables.append({ tables.append({
'name': table_name, 'name': table_name,
'columns': [r[1] for r in rows], 'columns': [r[1] for r in rows],
'table_rows': table_rows, 'table_rows': info['count'],
}) })
tables.sort(key=lambda t: t['name']) tables.sort(key=lambda t: t['name'])
views = await self.execute(name, 'select name from sqlite_master where type = "view"') views = await self.execute(name, 'select name from sqlite_master where type = "view"')
@ -467,7 +468,7 @@ class TableView(BaseView):
display_columns = display_columns[1:] display_columns = display_columns[1:]
rows = list(rows) rows = list(rows)
info = self.ds.inspect() info = self.ds.inspect()
table_rows = info[name]['tables'].get(table) table_rows = info[name]['tables'].get(table)['count']
next_value = None next_value = None
next_url = None next_url = None
if len(rows) > self.page_size: if len(rows) > self.page_size:
@ -588,7 +589,13 @@ class Datasette:
for r in conn.execute('select * from sqlite_master where type="table"') for r in conn.execute('select * from sqlite_master where type="table"')
] ]
for table in table_names: for table in table_names:
tables[table] = conn.execute('select count(*) from "{}"'.format(table)).fetchone()[0] tables[table] = {
'count': conn.execute('select count(*) from "{}"'.format(table)).fetchone()[0],
}
foreign_keys = get_all_foreign_keys(conn)
for table, info in foreign_keys.items():
tables[table]['foreign_keys'] = info
self._inspect[name] = { self._inspect[name] = {
'hash': m.hexdigest(), 'hash': m.hexdigest(),

Wyświetl plik

@ -197,3 +197,32 @@ def temporary_docker_directory(files, name, metadata, extra_options, extra_metad
finally: finally:
tmp.cleanup() tmp.cleanup()
os.chdir(saved_cwd) os.chdir(saved_cwd)
def get_all_foreign_keys(conn):
tables = [r[0] for r in conn.execute('select name from sqlite_master where type="table"')]
table_to_foreign_keys = {}
for table in tables:
table_to_foreign_keys[table] = {
'incoming': [],
'outgoing': [],
}
for table in tables:
infos = conn.execute(
'PRAGMA foreign_key_list([{}])'.format(table)
).fetchmany()
for info in infos:
if info is not None:
id, seq, table_name, from_, to_, on_update, on_delete, match = info
table_to_foreign_keys[table_name]['incoming'].append({
'other_table': table,
'column': to_,
'other_column': from_
})
table_to_foreign_keys[table]['outgoing'].append({
'other_table': table_name,
'column': from_,
'other_column': to_
})
return table_to_foreign_keys