class_registry issue with multiple classes of the same name
In my specific use case, I have several postgresql schemas that have a table with the same name. I find that only the first 2 appear to be correctly registered in the class_registry. In add_class in clsregistry.py, it detects if the name already exists and switches it to a _MultipleClassMarker. However, when subsequent classes are added with the same name, they aren't registered. One fix is to change add_class to look like this:
if classname in cls._decl_class_registry:
# class already exists.
existing = cls._decl_class_registry[classname]
if not isinstance(existing, _MultipleClassMarker):
existing = \
cls._decl_class_registry[classname] = \
_MultipleClassMarker([cls, existing])
else:
existing.add_item(cls) # Add the new class in this new else clause
else:
cls._decl_class_registry[classname] = cls
I'm pretty new to sqlalchemy, so it's possible this solution is shooting myself in the foot somewhere else.
Comments (7)
-
repo owner -
reporter Hey Mike. Thanks for getting back so quickly. Here is an example of 3 classes that will hit this problem. Put each class in its own file. Then import all 3 files. Then iterate through Base._decl_class_registry['Count'] and you'll see there are only 2 classes in there. I'd expect all 3 classes to be present. I'm running SQLAlchemy==1.0.7
class Count(Base): """Count sorted by date""" __tablename__ = 'Count' __table_args__ = {'schema': 'schema 1'} date = Column('Date', Date, primary_key=True) count = Column('Count', Integer) class Count(Base): """Count sorted by date""" __tablename__ = 'Count' __table_args__ = {'schema': 'schema 2'} date = Column('Date', Date, primary_key=True) count = Column('Count', Integer) class Count(Base): """Count sorted by date""" __tablename__ = 'Count' __table_args__ = {'schema': 'schema 3'} date = Column('Date', Date, primary_key=True) count = Column('Count', Integer)
Cheers
-
repo owner so, when you have classes of the same name, they must be referred to by module fully when you refer to them in a relationship. Run the following code with your three modules, assuming they are named "foo.a", "foo.b", and "foo.c", and you'll see they are all there:
from . import a, b, c from . import base registry = base.Base._decl_class_registry['_sa_module_registry'] print registry.resolve_attr("foo").a.Count print registry.resolve_attr("foo").b.Count print registry.resolve_attr("foo").c.Count
#! classics-MacBook-Pro:tmp classic$ python -m foo {'Count': <sqlalchemy.ext.declarative.clsregistry._MultipleClassMarker object at 0x10441ebd8>, '_sa_module_registry': <sqlalchemy.ext.declarative.clsregistry._ModuleMarker object at 0x104406350>} <class 'foo.a.Count'> <class 'foo.b.Count'> <class 'foo.c.Count'>
-
reporter Hey Mike. That will work for me. Thank you much for your time.
-
reporter - changed status to resolved
Mike's workaround works for my purposes.
-
repo owner yeah, these are all private APIs, we can at some point add a public API for all of this, if you have the need to refer to the registry outside of the usual way
-
reporter It would be useful for me, but I have a fairly obscure use case so I understand if it's not on the roadmap.
- Log in to comment
can you show me a few of these classes so I can understand specifically what you're doing and I can see for myself the name not going where its expected? thanks.