Для вашего # 3 вам необязательно объявлять пустые классы сущностей, чтобы использовать mapper
.Если вашему приложению не нужны причудливые свойства, вы можете просто использовать интроспекцию и метаклассы для моделирования существующих таблиц, не определяя их.Вот что я сделал:
mymetadata = sqlalchemy.MetaData()
myengine = sqlalchemy.create_engine(...)
def named_table(tablename):
u"return a sqlalchemy.Table object given a SQL table name"
return sqlalchemy.Table(tablename, mymetadata, autoload=True, autoload_with=myengine)
def new_bound_class(engine, table):
u"returns a new ORM class (processed by sqlalchemy.orm.mapper) given a sqlalchemy.Table object"
fieldnames = table.c.__dict__['_data']
def format_attributes(obj, transform):
attributes = [u'%s=%s' % (x, transform(x)) for x in fieldnames]
return u', '.join(attributes)
class DynamicORMClass(object):
def __init__(self, **kw):
u"Keyword arguments may be used to initialize fields/columns"
for key in kw:
if key in fieldnames: setattr(self, key, kw[key])
else: raise KeyError, '%s is not a valid field/column' % (key,)
def __repr__(self):
return u'%s(%s)' % (self.__class__.__name__, format_attributes(self, repr))
def __str__(self):
return u'%s(%s)' % (str(self.__class__), format_attributes(self, str))
DynamicORMClass.__doc__ = u"This is a dynamic class created using SQLAlchemy based on table %s" % (table,)
return sqlalchemy.orm.mapper(DynamicORMClass, table)
def named_orm_class(table):
u"returns a new ORM class (processed by sqlalchemy.orm.mapper) given a table name or object"
if not isinstance(table, Table):
table = named_table(table)
return new_bound_class(table)
Пример использования:
>>> myclass = named_orm_class('mytable')
>>> session = Session()
>>> obj = myclass(name='Fred', age=25, ...)
>>> session.add(obj)
>>> session.commit()
>>> print str(obj) # will print all column=value pairs
Я немного расширил свои версии new_bound_class
и named_orm_class
с помощью декораторов и т. Д., Чтобы обеспечитьдополнительные возможности, и вы тоже можете.Конечно, под прикрытием означает , объявив пустой класс сущностей.Но вам не нужно это делать, кроме этого один раз.
Это будет вас волновать, пока вы не решите, что вы устали делать все эти соединения самостоятельно, и почему можетеу меня просто есть атрибут объекта, который выполняет ленивый запрос выбора для связанных классов всякий раз, когда я его использую. Это , когда вы совершаете прыжок к декларативному (или эликсиру).