Hello, I am actually working on an existing project (an online-game) which is already advanced and pretty consequent.
My goal is to replace the save system actually based on Pickle by SQLAlchemy. Not so easy because I have to deal with the existing classes and there is a lot of work to do (about 400 classes to persist). I'm not sure to know what is the best way to proceed and I think that I require some help. *Let's look at the classes organization of the project :* <https://lh3.googleusercontent.com/-rfFB3ExzCXg/WeoZakWziFI/AAAAAAAAAVM/RACvOxxZmSgySRTIswpSNtYO9fd_ht-PgCLcBGAs/s1600/schema2.png> Every class which should be persistent has to be inherited from Stockable. It is already designed this way and I think that it would be too complicated to change that. Below Stockable, there is hundred of classes with their own hierarchy. For example, Character is inherited from Stockable and Player and NPC (Non-player Character) are inherited from Character. My problem today is that I don't know how to proceed regarding the metaclass "MetaBase". I am not able to use declarative_base() and MetaBase at the same time. There is a metabase conflict. I found some other topics about this problem on the internet and I tried several solutions, but still, it never works for me. *To resume, here is how it basically works without SQLAlchemy :* class MetaBase(type): def __init__(cls, nom, bases, contenu): type.__init__(cls, nom, bases, contenu) pass class Stockable(metaclass = MetaBase): def __init__(self): pass class Character(Stockable): def __init__(self): pass *Here is what I would like to do with SQLAlchemy:* from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta from sqlalchemy import Column, Integer Base = declarative_base() class MetaBase(DeclarativeMeta): def __init__(cls, nom, bases, contenu): super(MetaBase, cls).__init__(nom, bases, contenu) print("Init MetaBase") class Stockable(metaclass = MetaBase): def __init__(self): print("Init Stockable") class Character(Stockable, Base): __tablename__ = 'characters' id = Column(Integer, primary_key=True) def __init__(self, name): self.name = name print("Init character") jean = Character("Jean") print(jean.name) Here is what I get : >>> Traceback (most recent call last): File "C:\Users\Sven\Desktop\SQL Alchemy Tests\test2.py", line 10, in <module> class Stockable(metaclass = MetaBase): File "C:\Users\Sven\Desktop\SQL Alchemy Tests\test2.py", line 7, in __init__ super(MetaBase, cls).__init__(nom, bases, contenu) File "C:\Python34\lib\site-packages\sqlalchemy\ext\declarative\api.py", line 64, in __init__ _as_declarative(cls, classname, cls.__dict__) File "C:\Python34\lib\site-packages\sqlalchemy\ext\declarative\base.py", line 88, in _as_declarative _MapperConfig.setup_mapping(cls, classname, dict_) File "C:\Python34\lib\site-packages\sqlalchemy\ext\declarative\base.py", line 103, in setup_mapping cfg_cls(cls_, classname, dict_) File "C:\Python34\lib\site-packages\sqlalchemy\ext\declarative\base.py", line 125, in __init__ clsregistry.add_class(self.classname, self.cls) File "C:\Python34\lib\site-packages\sqlalchemy\ext\declarative\clsregistry.py", line 34, in add_class if classname in cls._decl_class_registry: AttributeError: type object 'Stockable' has no attribute '_decl_class_registry' >>> Does someone knows what it means and how it can be resolved ? *I tried other things and I found the following solution :* from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta from sqlalchemy import Column, Integer class MetaBase(DeclarativeMeta): def __init__(cls, nom, bases, contenu): super(MetaBase, cls).__init__(nom, bases, contenu) print("Init MetaBase") Base = declarative_base(metaclass = MetaBase) class Stockable(Base): __abstract__ = True def __init__(self): print("Init Stockable") class Character(Stockable): __tablename__ = 'characters' id = Column(Integer, primary_key=True) def __init__(self, name): self.name = name print("Init character") jean = Character("Jean") print(jean.name) It seems to work. I get the following result : >>> Init MetaBase Init MetaBase Init MetaBase Init compte Jean >>> However, the problem with this method is that I have to add *"__abstract__ = True" *to every class which is inherited by Stockable... so, about 400 classes. It is not very clean. Is it possible to avoid that by using something similar to my first code ? It would be great ! Thank you very much. Sven -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.