kopia lustrzana https://github.com/simonw/datasette
Moved expand_foreign_keys method to Database
Refs #620 Also fixed a few places that were calling ds.execute() instead of db.execute()querystring-fks
rodzic
eb61845141
commit
dcc5cd425a
|
@ -352,43 +352,6 @@ class Datasette:
|
|||
log_sql_errors=log_sql_errors,
|
||||
)
|
||||
|
||||
async def expand_foreign_keys(self, database, table, column, values, fks=None):
|
||||
"Returns dict mapping (column, value) -> label"
|
||||
labeled_fks = {}
|
||||
db = self.databases[database]
|
||||
foreign_keys = fks or await db.foreign_keys_for_table(table)
|
||||
# Find the foreign_key for this column
|
||||
try:
|
||||
fk = [
|
||||
foreign_key
|
||||
for foreign_key in foreign_keys
|
||||
if foreign_key["column"] == column
|
||||
][0]
|
||||
except IndexError:
|
||||
return {}
|
||||
label_column = await db.label_column_for_table(fk["other_table"])
|
||||
if not label_column:
|
||||
return {(fk["column"], value): str(value) for value in values}
|
||||
labeled_fks = {}
|
||||
sql = """
|
||||
select {other_column}, {label_column}
|
||||
from {other_table}
|
||||
where {other_column} in ({placeholders})
|
||||
""".format(
|
||||
other_column=escape_sqlite(fk["other_column"]),
|
||||
label_column=escape_sqlite(label_column),
|
||||
other_table=escape_sqlite(fk["other_table"]),
|
||||
placeholders=", ".join(["?"] * len(set(values))),
|
||||
)
|
||||
try:
|
||||
results = await self.execute(database, sql, list(set(values)))
|
||||
except QueryInterrupted:
|
||||
pass
|
||||
else:
|
||||
for id, value in results:
|
||||
labeled_fks[(fk["column"], id)] = value
|
||||
return labeled_fks
|
||||
|
||||
def absolute_url(self, request, path):
|
||||
url = urllib.parse.urljoin(request.url, path)
|
||||
if url.startswith("http://") and self.config("force_https_urls"):
|
||||
|
|
|
@ -10,6 +10,7 @@ from .utils import (
|
|||
detect_fts,
|
||||
detect_primary_keys,
|
||||
detect_spatialite,
|
||||
escape_sqlite,
|
||||
get_all_foreign_keys,
|
||||
get_outbound_foreign_keys,
|
||||
sqlite_timelimit,
|
||||
|
@ -217,6 +218,42 @@ class Database:
|
|||
lambda conn: get_outbound_foreign_keys(conn, table)
|
||||
)
|
||||
|
||||
async def expand_foreign_keys(self, table, column, values, fks=None):
|
||||
"Returns dict mapping (column, value) -> label"
|
||||
labeled_fks = {}
|
||||
foreign_keys = fks or await self.foreign_keys_for_table(table)
|
||||
# Find the foreign_key for this column
|
||||
try:
|
||||
fk = [
|
||||
foreign_key
|
||||
for foreign_key in foreign_keys
|
||||
if foreign_key["column"] == column
|
||||
][0]
|
||||
except IndexError:
|
||||
return {}
|
||||
label_column = await self.label_column_for_table(fk["other_table"])
|
||||
if not label_column:
|
||||
return {(fk["column"], value): str(value) for value in values}
|
||||
labeled_fks = {}
|
||||
sql = """
|
||||
select {other_column}, {label_column}
|
||||
from {other_table}
|
||||
where {other_column} in ({placeholders})
|
||||
""".format(
|
||||
other_column=escape_sqlite(fk["other_column"]),
|
||||
label_column=escape_sqlite(label_column),
|
||||
other_table=escape_sqlite(fk["other_table"]),
|
||||
placeholders=", ".join(["?"] * len(set(values))),
|
||||
)
|
||||
try:
|
||||
results = await self.execute(sql, list(set(values)))
|
||||
except QueryInterrupted:
|
||||
pass
|
||||
else:
|
||||
for id, value in results:
|
||||
labeled_fks[(fk["column"], id)] = value
|
||||
return labeled_fks
|
||||
|
||||
async def hidden_table_names(self):
|
||||
# Mark tables 'hidden' if they relate to FTS virtual tables
|
||||
hidden_tables = [
|
||||
|
|
|
@ -139,6 +139,7 @@ class ColumnFacet(Facet):
|
|||
facet_size = self.ds.config("default_facet_size")
|
||||
suggested_facets = []
|
||||
already_enabled = [c["config"]["simple"] for c in self.get_configs()]
|
||||
database = self.ds.databases[self.database]
|
||||
for column in columns:
|
||||
if column in already_enabled:
|
||||
continue
|
||||
|
@ -152,8 +153,7 @@ class ColumnFacet(Facet):
|
|||
)
|
||||
distinct_values = None
|
||||
try:
|
||||
distinct_values = await self.ds.execute(
|
||||
self.database,
|
||||
distinct_values = await database.execute(
|
||||
suggested_facet_sql,
|
||||
self.params,
|
||||
truncate=False,
|
||||
|
@ -182,6 +182,7 @@ class ColumnFacet(Facet):
|
|||
async def facet_results(self):
|
||||
facet_results = {}
|
||||
facets_timed_out = []
|
||||
database = self.ds.databases[self.database]
|
||||
|
||||
qs_pairs = self.get_querystring_pairs()
|
||||
|
||||
|
@ -200,8 +201,7 @@ class ColumnFacet(Facet):
|
|||
col=escape_sqlite(column), sql=self.sql, limit=facet_size + 1
|
||||
)
|
||||
try:
|
||||
facet_rows_results = await self.ds.execute(
|
||||
self.database,
|
||||
facet_rows_results = await database.execute(
|
||||
facet_sql,
|
||||
self.params,
|
||||
truncate=False,
|
||||
|
@ -222,8 +222,8 @@ class ColumnFacet(Facet):
|
|||
if self.table:
|
||||
# Attempt to expand foreign keys into labels
|
||||
values = [row["value"] for row in facet_rows]
|
||||
expanded = await self.ds.expand_foreign_keys(
|
||||
self.database, self.table, column, values
|
||||
expanded = await database.expand_foreign_keys(
|
||||
self.table, column, values
|
||||
)
|
||||
else:
|
||||
expanded = {}
|
||||
|
|
|
@ -558,17 +558,13 @@ class TableView(RowTableShared):
|
|||
if request.raw_args.get("_timelimit"):
|
||||
extra_args["custom_time_limit"] = int(request.raw_args["_timelimit"])
|
||||
|
||||
results = await self.ds.execute(
|
||||
database, sql, params, truncate=True, **extra_args
|
||||
)
|
||||
results = await db.execute(sql, params, truncate=True, **extra_args)
|
||||
|
||||
# Number of filtered rows in whole set:
|
||||
filtered_table_rows_count = None
|
||||
if count_sql:
|
||||
try:
|
||||
count_rows = list(
|
||||
await self.ds.execute(database, count_sql, from_sql_params)
|
||||
)
|
||||
count_rows = list(await db.execute(count_sql, from_sql_params))
|
||||
filtered_table_rows_count = count_rows[0][0]
|
||||
except QueryInterrupted:
|
||||
pass
|
||||
|
@ -643,12 +639,8 @@ class TableView(RowTableShared):
|
|||
values = [row[column_index] for row in rows]
|
||||
# Expand them
|
||||
expanded_labels.update(
|
||||
await self.ds.expand_foreign_keys(
|
||||
database,
|
||||
table,
|
||||
column,
|
||||
values,
|
||||
fks=[p[0] for p in expandable_columns],
|
||||
await db.expand_foreign_keys(
|
||||
table, column, values, fks=[p[0] for p in expandable_columns],
|
||||
)
|
||||
)
|
||||
if expanded_labels:
|
||||
|
@ -831,7 +823,7 @@ class RowView(RowTableShared):
|
|||
params = {}
|
||||
for i, pk_value in enumerate(pk_values):
|
||||
params["p{}".format(i)] = pk_value
|
||||
results = await self.ds.execute(database, sql, params, truncate=True)
|
||||
results = await db.execute(sql, params, truncate=True)
|
||||
columns = [r[0] for r in results.description]
|
||||
rows = list(results.rows)
|
||||
if not rows:
|
||||
|
@ -913,7 +905,7 @@ class RowView(RowTableShared):
|
|||
]
|
||||
)
|
||||
try:
|
||||
rows = list(await self.ds.execute(database, sql, {"id": pk_values[0]}))
|
||||
rows = list(await db.execute(sql, {"id": pk_values[0]}))
|
||||
except sqlite3.OperationalError:
|
||||
# Almost certainly hit the timeout
|
||||
return []
|
||||
|
|
Ładowanie…
Reference in New Issue