Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Some spaghetti to produce a SQLAlchemy Table *string* from a SQLA model.
import re
from black import format_str, FileMode
def convert_tablemapping_to_table_object(model) -> str:
schema_name = model.__table_args__["schema"].lower()
table_repr = repr(model.__table__)
header_str, *columns = table_repr.split("Column(")
# from https://stackoverflow.com/a/4145486/4386191
FIND_LOWERCASE = lambda pat: pat.group(1).lower()
new_cols = []
for column in columns:
replaced_default_clause = re.sub(
r"DefaultClause\(('[a-zA-Z_]+'), for_update=False\)\)", r"\1)", column
)
replaced_table_arg = re.sub(r"(table=[a-zA-Z_<>]+[\), ]+)", "", replaced_default_clause)
# from https://stackoverflow.com/a/4145486/4386191
lowercased_names = re.sub(r"('[A-Z_]+')", FIND_LOWERCASE, replaced_table_arg)
# this is a band-aid, the closing parenthesis of the last Column was removed above
if "schema=" in lowercased_names:
lowercased_names = lowercased_names.split("schema=")[0]
if lowercased_names.count("(") != lowercased_names.count(")") - 1:
if lowercased_names.endswith("), "):
lowercased_names = lowercased_names[:-3] + ")), "
else:
lowercased_names += ")"
lowercased_names
new_cols.append(lowercased_names)
lowercased_header_str = re.sub(r"('[A-Z_]+')", FIND_LOWERCASE, header_str)
rejoined = lowercased_header_str + "Column(" + "Column(".join(new_cols)
meta = rejoined.replace("MetaData(bind=None)", "metadata_obj") + f"schema='{schema_name}')"
return format_str(meta, mode=FileMode())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment