I recently upgraded from SQLAlchemy 1.2 to 1.3 and one of the relationships 
I have no longer works. I'm trying to reflect an existing schema and 
provide a base class that provides some helper methods to all of my ORM 
classes. I'm also trying to defer reflection to after the ORM classes are 
prepared.

The error I'm seeing is:

  File "scratch.py", line 98, in <module>
    a = session.query(A)
  File "lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1544, 
in query
    return self._query_cls(entities, self, **kwargs)
  File "lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 168, in 
__init__
    self._set_entities(entities)
  File "lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 200, in 
_set_entities
    self._set_entity_selectables(self._entities)
  File "lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 231, in 
_set_entity_selectables
    ent.setup_entity(*d[entity])
  File "lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 4121, in 
setup_entity
    self._with_polymorphic = ext_info.with_polymorphic_mappers
  File "lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 
855, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2135, in 
_with_polymorphic_mappers
    configure_mappers()
  File "lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 3248, in 
configure_mappers
    mapper._post_configure_properties()
  File "lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1947, in 
_post_configure_properties
    prop.init()
  File "lib/python2.7/site-packages/sqlalchemy/orm/interfaces.py", line 196, 
in init
    self.do_init()
  File "lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 
1860, in do_init
    self._process_dependent_arguments()
  File "lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 
1889, in _process_dependent_arguments
    setattr(self, attr, attr_value())
  File 
"lib/python2.7/site-packages/sqlalchemy/ext/declarative/clsregistry.py", 
line 294, in __call__
    x = eval(self.arg, globals(), self._dict)
  File "<string>", line 1, in <module>
  File "lib/python2.7/site-packages/sqlalchemy/util/_collections.py", line 
734, in __missing__
    self[key] = val = self.creator(key)
  File 
"lib/python2.7/site-packages/sqlalchemy/ext/declarative/clsregistry.py", 
line 286, in _access_cls
    value = resolv(key)
  File "lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", 
line 778, in _resolve
    cls._reflect_table(t1, engine)
  File "lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", 
line 811, in _reflect_table
    schema=table.schema,
  File "<string>", line 2, in __new__
  File "lib/python2.7/site-packages/sqlalchemy/util/deprecations.py", line 
128, in warned
    return fn(*args, **kwargs)
  File "lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 492, in 
__new__
    table._init_existing(*args, **kw)
  File "lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 708, in 
_init_existing
    _extend_on=_extend_on,
  File "lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 619, in 
_autoload
    _extend_on=_extend_on,
  File "lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2160, 
in run_callable
    return conn.run_callable(callable_, *args, **kwargs)
  File "lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1612, 
in run_callable
    return callable_(self, *args, **kwargs)
  File "lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 459, 
in reflecttable
    table, include_columns, exclude_columns, resolve_fks, **opts
  File "lib/python2.7/site-packages/sqlalchemy/engine/reflection.py", line 
629, in reflecttable
    table_name, schema, **table.dialect_kwargs
  File "lib/python2.7/site-packages/sqlalchemy/engine/reflection.py", line 
314, in get_table_options
    self.bind, table_name, schema, info_cache=self.info_cache, **kw
  File "<string>", line 2, in get_table_options
  File "lib/python2.7/site-packages/sqlalchemy/engine/reflection.py", line 
56, in cache
    ret = fn(self, con, *args, **kw)
  File "lib/python2.7/site-packages/sqlalchemy/dialects/mysql/base.py", 
line 2499, in get_table_options
    connection, table_name, schema, **kw
  File "lib/python2.7/site-packages/sqlalchemy/dialects/mysql/base.py", 
line 2745, in _parsed_state_or_create
    info_cache=kw.get("info_cache", None),
  File "<string>", line 2, in _setup_parser
  File "lib/python2.7/site-packages/sqlalchemy/engine/reflection.py", line 
56, in cache
    ret = fn(self, con, *args, **kw)
  File "lib/python2.7/site-packages/sqlalchemy/dialects/mysql/base.py", 
line 2773, in _setup_parser
    connection, None, charset, full_name=full_name
  File "lib/python2.7/site-packages/sqlalchemy/dialects/mysql/base.py", 
line 2876, in _show_create_table
    raise exc.NoSuchTableError(full_name)
sqlalchemy.exc.NoSuchTableError: `join`


Here's a repro based on the example from the docs (
https://docs.sqlalchemy.org/en/13/orm/join_conditions.html?highlight=secondary%20composite#composite-secondary-joins
)

from sqlalchemy import Column, Integer, ForeignKey, create_engine
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
from sqlalchemy.orm import relationship, Session

_Base = declarative_base()


class Base(_Base, DeferredReflection):
 __abstract__ = True


class A(Base):
 __tablename__ = 'a'

 id = Column(Integer, primary_key=True)
 b_id = Column(ForeignKey('b.id'))

 d = relationship("D",
 secondary="join(B, D, B.d_id == D.id)."
 "join(C, C.d_id == D.id)",
 primaryjoin="and_(A.b_id == B.id, A.id == C.a_id)",
 secondaryjoin="D.id == B.d_id",
 uselist=True
 )


class B(Base):
 __tablename__ = 'b'

 id = Column(Integer, primary_key=True)
 d_id = Column(ForeignKey('d.id'))


class C(Base):
 __tablename__ = 'c'

 id = Column(Integer, primary_key=True)
 a_id = Column(ForeignKey('a.id'))
 d_id = Column(ForeignKey('d.id'))


class D(Base):
 __tablename__ = 'd'

 id = Column(Integer, primary_key=True)


engine = 
create_engine("mysql+mysqldb://[email protected]:3306/testing?charset=utf8mb4&binary_prefix=true",
 echo=True)
engine.execute("""
DROP DATABASE testing;
CREATE DATABASE testing;
USE testing;

CREATE TABLE d (
 id int unsigned auto_increment,
 primary key (id)
) engine=innodb;

CREATE TABLE b (
 id int unsigned auto_increment,
 d_id int unsigned default null,
 primary key (id),
 foreign key (d_id) references `d` (id)
) engine=innodb;

CREATE TABLE a (
 id int unsigned auto_increment,
 b_id int unsigned default null,
 primary key (id),
 foreign key (b_id) references `b` (id)
) engine=innodb;

CREATE TABLE c (
 id int unsigned auto_increment,
 a_id int unsigned default null,
 d_id int unsigned default null,
 primary key (id),
 foreign key (a_id) references `a` (id),
 foreign key (d_id) references `d` (id)
) engine=innodb;

INSERT INTO d (id) values (1), (2), (3);
INSERT INTO b (d_id) values (1), (1), (2);
INSERT INTO a (b_id) values (2), (3), (1);
INSERT INTO c (a_id, d_id) values (1, 1), (1, 2), (2, 3);
""")

Base.metadata.reflect(bind=engine)

A.prepare(engine)
B.prepare(engine)
C.prepare(engine)
D.prepare(engine)

engine = 
create_engine("mysql+mysqldb://[email protected]:3306/testing?charset=utf8mb4&binary_prefix=true",
 echo=True)
session = Session(engine)

a = session.query(A)
for _a in a:
 print(a)
 if _a.d:
 print(list(_a.d))


I've verified that the error only happens when I defer reflection. I.e. I 
remove the DefferedReflection base class from _Base and I comment out the 
A.prepare(engine)... lines.

Has anyone else run into this?

Thanks!

-- 
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/b6e3e875-3d17-49c0-b5f6-70d7215ea3f0%40googlegroups.com.

Reply via email to