對於你的#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
多一點與裝飾等,以提供額外的功能,你也可以做到。當然,在封面下,它是宣佈一個空的實體類。但你不必這樣做,除了這一次。
這會讓你感到厭倦,直到你決定厭倦自己完成所有這些連接,並且爲什麼我無法獲得一個對象屬性,該對象屬性會在我使用它時對相關類進行惰性選擇查詢。 這是,當你跳躍到聲明(或Elixir)。
+1感謝您解釋表繼承。 – wberry