I need to create many similar databases in different locations in a for-loop. In the beginning of the loop, I create the engine to a new path_sql_db
on disk.
engine = sa.create_engine("sqlite:///{}".format(path_sql_db), echo=0, listeners=[util_sa.ForeignKeysListener()])
Session = sa.orm.sessionmaker(bind=engine)
session = Session()
Then I have my Tables in several modules inherit from DB_Base which was defined in an external module;
from sqlalchemy.ext.declarative import declarative_base
DB_Base = declarative_base()
The problem is that during my next iteration of the for-loop, I can't create my tables since they still exist somewhere?
InvalidRequestError: Table 'vector_var01' is already defined for this MetaData instance.
Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
I've tried to MetaData.drop_all() from the engine;
meta = sa.MetaData(bind = engine)
meta.reflect()
meta.drop_all()
session.close()
And also from the Base;
DB_Base.metadata.bind = engine
DB_Base.metadata.reflect()
DB_Base.metadata.drop_all()
With no success, I'm still just flailing around in the dark here.
Which MetaData instance is the error referring to? How can I completely reset the state of my database code?
EDIT
Ok I tracked down the problem. I'm trying to dynamically generate ORM tables. I am studying optimization routines and storing design space variables in their own tables, one row per possible value of the variable.
Minimal example causing error;
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
name = Column(String(50))
def generate_variable_table_class(name):
"""This is a helper function which dynamically creates a new ORM enabled class
The table will hold the individual values of each variable
Individual values are stored as a string
"""
class NewTable( Base ):
__tablename__ = "vector_{}".format(name)
id = Column(Integer, primary_key=True)
value = Column(String(16), nullable=False, unique=True)
def __init__(self,value):
self.value = str(value)
def __str__(self):
return self.value
def __repr__(self):
return self.value
NewTable.__name__ = "vector_ORM_{}".format(name)
return NewTable
if __name__ == "__main__":
for name in 'asfd', 'jkl', 'xyz':
print("For loop: ",name)
engine = create_engine(r'sqlite:///c:\testdelete\{}.sql'.format(name))
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
bunch_o_foos = [Foo(name = i) for i in range(10)]
session.add_all(bunch_o_foos)
session.commit()
for foo in bunch_o_foos:
print(foo.id)
variables = [generate_variable_table_class(i) for i in range(10)]
Which is actually the same as this question; Dynamic Python Class Definition in SQLAlchemy. Is this not possible?