[英]mapping one class to two tables from different database in SQLAlchemy
[英]Sqlalchemy: Mapping a class to different tables depending on attribute
我正在尝试写入包含以下形式的多个表的现有数据库
total_usage_<application>:
id
version
date
其中<application>
在许多字符串上运行,例如“ appl1”,“ appl2”等。现在,我想使用SQLAlchemy创建单个类,例如
class DBEntry:
id = ''
application = ''
version = ''
date = ''
这样DBEntry的实例foo
被映射到表"total_usage_" + foo.application
。 如何做到这一点?
好的,请看下面的示例,它是独立的,可能会向您显示一种完成此操作的方法。 它假定您在启动程序时就知道app_name
,并且假定表名遵循某种命名约定,显然,您可以适应您的需要,或者通过在每个映射的类中重写__tablename__
来完全手动配置它。
但是主要思想是将配置包装到一个函数中(也可以使用预先带有预定义常量的模块导入来完成)。
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.