Hi Everyone, 

SQLAlchemy nicely reflects tables and builds model using automap. When 
providing the parameter shema to reflect, tables from that schema are 
discovered. I've noticed that tables from other schemas will also be 
included if there is a foreign key to the other schema. 

It's all good but what should I do to reflect and automap *only* tables 
from the schema i.e. ignore tables and relationships to other schemas?

I've done it by removing unwanted:

   - foreign keys that refer to other schemas from table objects
   - foreign keys constraints that refer to other schemas from table objects
   - foreign keys that refer to other schemas from column objects
   
I've attached the script that does what I've explained above.

It seems to work and no errors when reflect, automap and making queries 
even with joins but is it OK to do it this way? 

Much appreciate any comments.

Cheers,
Michal

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/5984bc30-5325-4053-b42e-694f96af9516n%40googlegroups.com.
import functools

from sqlalchemy import (
    create_engine,
    MetaData,
    PrimaryKeyConstraint,
    ForeignKeyConstraint
)
from sqlalchemy.ext.automap import automap_base


def is_target_in_schema(target_full_name, schema):
    """Checks if target_full_name is in the schema.

    The target_full_name is dot separated [schema].[table].[column]
    It may be [table].[column] when
    """
    if schema is None:
        schema = ''

    try:
        referred_schema = target_full_name.split('.')[-3]
    except IndexError:
        referred_schema = ''

    return schema == referred_schema


def pk_and_local_fk_constraints(c, db_schema=None):
    """Function for filter.

    Filter out foreign key constraints that point to different schema.

    """
    if isinstance(c, PrimaryKeyConstraint):
        return True

    if isinstance(c, ForeignKeyConstraint):
        target_fullname = c.elements[0].target_fullname
        return is_target_in_schema(target_fullname, db_schema)

    return False


connstr = 'mssql://test:[email protected]:1433/test?driver=FreeTDS&TDS_Version=7.0'
engine = create_engine(connstr)
db_schema = 'Customer'
metadata = MetaData()
metadata.reflect(engine, schema=db_schema, resolve_fks=False)

for table in metadata.tables.values():
    # removes fk from columns that refer outside the schema
    for col in table.columns:
        col.foreign_keys = {
            fk for fk in col.foreign_keys
            if is_target_in_schema(fk.target_fullname, db_schema)
        }

    # removes fk that refer outside the schema
    table.foreign_keys = {
        fk for fk in table.foreign_keys
        if is_target_in_schema(fk.target_fullname, db_schema)
    }

    # keep only pk constraints and fk constraints within the schema
    table.constraints = set(
        filter(
            functools.partial(
                pk_and_local_fk_constraints, db_schema=db_schema
            ),
            table.constraints
        )
    )

Base = automap_base(metadata=metadata)
Base.prepare(engine)
classes = [(c.__name__) for c in Base.classes]
classes.sort()
print(classes)
print('Dealers' in classes)

# output, Dealers not present in reflected model
# >>>> ['People', 'Service', 'Vehicles']
# >>>> False

Reply via email to