kvesteri / sqlalchemy-utils

Various utility functions and datatypes for SQLAlchemy.
Other
1.27k stars 321 forks source link

Reflected database: 'dependent_objects' raises AttributeError: <object> has no attribute '_decl_class_registry' #497

Open ScissorHill opened 3 years ago

ScissorHill commented 3 years ago

Thanks for this very useful project. I'm using SQLAlchemy on a reflected database as follows:

from sqlalchemy import create_engine, select, MetaData, Table, func, inspect
from sqlalchemy.orm import Session
from sqlalchemy.ext.automap import automap_base
import pymysql

metadata = MetaData()
db_connection_str = f'mysql+pymysql://{db_user}:{db_password}@localhost/{db_name}'
Base = automap_base()
Base.prepare(db_connection, reflect=False)

Event = Base.classes.event # table whose dependents I need to find

with Session(bind=db_connection) as session:
    first_result = session.execute(
        select(Event).where(Event.id==401671)
    )
first_event = first_result.fetchall()[0][0]
dependent_objects(first_event)

This raises the following error:

AttributeError                            Traceback (most recent call last)
<ipython-input-43-4280f04567c7> in <module>
----> 1 dependent_objects(first_event)

~/src/sqlalchemy-utils/sqlalchemy_utils/functions/foreign_keys.py in dependent_objects(obj, foreign_keys)
    266 
    267     chain = QueryChain([])
--> 268     classes = obj.__class__._decl_class_registry
    269 
    270     for table, keys in group_foreign_keys(foreign_keys):

AttributeError: type object 'event' has no attribute '_decl_class_registry'

Incidentally, I'm using SQLAlchemy 1.4, and so I've applied this patch locally. Not sure if it's a version issue, though.

get_referencing_foreign_keys(Event) works rather well. I'm looking for exactly the inverse, i.e. ancestors rather than descendants.

alanhamlett commented 3 years ago

The fix: https://stackoverflow.com/a/66666783/1290627