Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamin-kirkbride committed Jan 8, 2022
1 parent 4f9dbda commit c065362
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
@@ -0,0 +1,3 @@
{
"python.pythonPath": "/home/bkirkbride/foo/eralchemy/.venv/bin/python"
}
42 changes: 25 additions & 17 deletions eralchemy/sqla.py
Expand Up @@ -3,39 +3,41 @@
This class allow to transform SQLAlchemy metadata to the intermediary syntax.
"""

from eralchemy.models import Relation, Column, Table
import sys

from sqlalchemy.exc import CompileError

from eralchemy.models import Column, Relation, Table

if sys.version_info[0] == 3:
unicode = str


def relation_to_intermediary(fk):
"""Transform an SQLAlchemy ForeignKey object to it's intermediary representation. """
"""Transform an SQLAlchemy ForeignKey object to it's intermediary representation."""
return Relation(
right_col=format_name(fk.parent.table.fullname),
left_col=format_name(fk._column_tokens[1]),
right_cardinality='?',
left_cardinality='*',
right_cardinality="?",
left_cardinality="*",
)


def format_type(typ):
""" Transforms the type into a nice string representation. """
"""Transforms the type into a nice string representation."""
try:
return unicode(typ)
except CompileError:
return 'Null'
return "Null"


def format_name(name):
""" Transforms the name into a nice string representation. """
"""Transforms the name into a nice string representation."""
return unicode(name)


def column_to_intermediary(col, type_formatter=format_type):
"""Transform an SQLAlchemy Column object to it's intermediary representation. """
"""Transform an SQLAlchemy Column object to it's intermediary representation."""
return Column(
name=col.name,
type=type_formatter(col.type),
Expand All @@ -44,41 +46,47 @@ def column_to_intermediary(col, type_formatter=format_type):


def table_to_intermediary(table):
"""Transform an SQLAlchemy Table object to it's intermediary representation. """
"""Transform an SQLAlchemy Table object to it's intermediary representation."""
return Table(
name=table.fullname,
columns=[column_to_intermediary(col) for col in table.c._data.values()]
columns=[column_to_intermediary(col) for col in table.c._colset],
)


def metadata_to_intermediary(metadata):
""" Transforms SQLAlchemy metadata to the intermediary representation. """
"""Transforms SQLAlchemy metadata to the intermediary representation."""
tables = [table_to_intermediary(table) for table in metadata.tables.values()]
relationships = [relation_to_intermediary(fk) for table in metadata.tables.values() for fk in table.foreign_keys]
relationships = [
relation_to_intermediary(fk)
for table in metadata.tables.values()
for fk in table.foreign_keys
]
return tables, relationships


def declarative_to_intermediary(base):
""" Transform an SQLAlchemy Declarative Base to the intermediary representation. """
"""Transform an SQLAlchemy Declarative Base to the intermediary representation."""
return metadata_to_intermediary(base.metadata)


def name_for_scalar_relationship(base, local_cls, referred_cls, constraint):
""" Overriding naming schemes. """
"""Overriding naming schemes."""
name = referred_cls.__name__.lower() + "_ref"
return name


def database_to_intermediary(database_uri, schema=None):
""" Introspect from the database (given the database_uri) to create the intermediary representation. """
from sqlalchemy.ext.automap import automap_base
"""Introspect from the database (given the database_uri) to create the intermediary representation."""
from sqlalchemy import create_engine
from sqlalchemy.ext.automap import automap_base

Base = automap_base()
engine = create_engine(database_uri)
if schema is not None:
Base.metadata.schema = schema

# reflect the tables
Base.prepare(engine, reflect=True, name_for_scalar_relationship=name_for_scalar_relationship)
Base.prepare(
engine, reflect=True, name_for_scalar_relationship=name_for_scalar_relationship
)
return declarative_to_intermediary(Base)
Binary file added erd.pdf
Binary file not shown.

0 comments on commit c065362

Please sign in to comment.