Skip to content

Commit

Permalink
feat: extra table metadata for Google Sheets (apache#14775)
Browse files Browse the repository at this point in the history
* feat: GSheets extra table metadata

* Bump version
  • Loading branch information
betodealmeida authored and cccs-RyanS committed Dec 17, 2021
1 parent 65536dd commit d6a327b
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def get_git_sha():
"exasol": ["sqlalchemy-exasol>=2.1.0, <2.2"],
"excel": ["xlrd>=1.2.0, <1.3"],
"firebird": ["sqlalchemy-firebird>=0.7.0, <0.8"],
"gsheets": ["shillelagh[gsheetsapi]>=0.5, <0.6"],
"gsheets": ["shillelagh[gsheetsapi]>=0.7.1, <0.8"],
"hana": ["hdbcli==2.4.162", "sqlalchemy_hana==0.4.0"],
"hive": ["pyhive[hive]>=0.6.1", "tableschema", "thrift>=0.11.0, <1.0.0"],
"impala": ["impyla>0.16.2, <0.17"],
Expand Down
42 changes: 31 additions & 11 deletions superset-frontend/src/SqlLab/components/TableElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface Table {
partitionQuery: string;
latest: object[];
};
metadata?: Record<string, string>;
indexes?: object[];
selectStar?: string;
view?: string;
Expand Down Expand Up @@ -91,7 +92,8 @@ const TableElement = ({ table, actions, ...props }: TableElementProps) => {
};

const renderWell = () => {
let header;
let partitions;
let metadata;
if (table.partitions) {
let partitionQuery;
let partitionClipBoard;
Expand All @@ -111,18 +113,36 @@ const TableElement = ({ table, actions, ...props }: TableElementProps) => {
.map(([key, value]) => `${key}=${value}`)
.join('/');

header = (
<Card size="small">
<div>
<small>
{t('latest partition:')} {latest}
</small>{' '}
{partitionClipBoard}
</div>
</Card>
partitions = (
<div>
<small>
{t('latest partition:')} {latest}
</small>{' '}
{partitionClipBoard}
</div>
);
}
return header;

if (table.metadata) {
metadata = Object.entries(table.metadata).map(([key, value]) => (
<div>
<small>
<strong>{key}:</strong> {value}
</small>
</div>
));
}

if (!partitions && !metadata) {
return null;
}

return (
<Card size="small">
{partitions}
{metadata}
</Card>
);
};

const renderControls = () => {
Expand Down
4 changes: 4 additions & 0 deletions superset-frontend/src/SqlLab/reducers/getInitialState.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ export default function getInitialState({
foreignKeys,
indexes,
dataPreviewQueryId,
partitions,
metadata,
} = tableSchema.description;
const table = {
dbId: tableSchema.database_id,
Expand All @@ -133,6 +135,8 @@ export default function getInitialState({
primaryKey,
foreignKeys,
indexes,
partitions,
metadata,
};
tables.push(table);
});
Expand Down
25 changes: 24 additions & 1 deletion superset/db_engine_specs/gsheets.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import json
import re
from typing import Any, Dict, Optional, Pattern, Tuple
from contextlib import closing
from typing import Any, Dict, Optional, Pattern, Tuple, TYPE_CHECKING

from flask_babel import gettext as __
from sqlalchemy.engine.url import URL
Expand All @@ -24,6 +26,10 @@
from superset.db_engine_specs.sqlite import SqliteEngineSpec
from superset.errors import SupersetErrorType

if TYPE_CHECKING:
from superset.models.core import Database


SYNTAX_ERROR_REGEX = re.compile('SQLError: near "(?P<server_error>.*?)": syntax error')


Expand Down Expand Up @@ -54,3 +60,20 @@ def modify_url_for_impersonation(
user = security_manager.find_user(username=username)
if user and user.email:
url.query["subject"] = user.email

@classmethod
def extra_table_metadata(
cls, database: "Database", table_name: str, schema_name: str,
) -> Dict[str, Any]:
engine = cls.get_engine(database, schema=schema_name)
with closing(engine.raw_connection()) as conn:
cursor = conn.cursor()
cursor.execute(f'SELECT GET_METADATA("{table_name}")')
results = cursor.fetchone()[0]

try:
metadata = json.loads(results)
except Exception: # pylint: disable=broad-except
metadata = {}

return {"metadata": metadata["extra"]}

0 comments on commit d6a327b

Please sign in to comment.