I'm trying to write to an existing database consisting of multiple tables of the following form
total_usage_<application>:
id
version
date
where <application>
runs over a number of strings, say "appl1", "appl2" etc. Now I would like to use SQLAlchemy to create a single class like
class DBEntry:
id = ''
application = ''
version = ''
date = ''
such that an instance foo
of DBEntry gets mapped to the table "total_usage_" + foo.application
. How can this be achieved?
OK, please take a look at example below, which is self-contained and might show you one way this can be done. It assumes that you know the app_name
when you start your program, as well as it assumes that table names follow some naming convention, which obviously you can adapt to your needs or have it completely manually configured by overriding __tablename__
in each mapped class.
But the main idea is that the configuration is wrapped into a function (which can be done also using module import with pre-defined constant beforehand).
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, scoped_session, sessionmaker
def camel_to_under(name):
import re
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
def configure_database(app_name):
""" @return: dictionary with all the classes mapped to proper tables for
specific application. """
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base
class Base(object):
# docs: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#augmenting-the-base
@declared_attr
def __tablename__(cls):
return camel_to_under(cls.__name__) + "_" + app_name
def __repr__(self):
attrs = class_mapper(self.__class__).column_attrs # only columns
# attrs = class_mapper(self.__class__).attrs # show also relationships
return u"{}({})".format(self.__class__.__name__,
', '.join('%s=%r' % (k.key, getattr(self, k.key))
for k in sorted(attrs)
)
)
Base = declarative_base(cls=Base)
class Class1(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
class Class1Child(Base):
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey(Class1.id))
name = Column(String)
# relationships
parent = relationship(Class1, backref="children")
# return locals()
return {
"app_name": app_name,
"Base": Base,
"Class1": Class1,
"Class1Child": Class1Child,
}
def _test():
""" Little test for the app. """
engine = create_engine(u'sqlite:///:memory:', echo=True)
session = scoped_session(sessionmaker(bind=engine))
app_name = "app1"
x = configure_database(app_name)
# assign real names
app_name = x["app_name"]
Base = x["Base"]
Class1 = x["Class1"]
Class1Child = x["Class1Child"]
# create DB model (not required in production)
Base.metadata.create_all(engine)
# test data
cc = Class1Child(name="child-11")
c1 = Class1(name="some instance", children=[cc])
session.add(c1)
session.commit()
_test()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.