On May 5, 2010, at 5:12 PM, Michael Bayer wrote:

> 
> Since Python allows dynamic generation of classes, there are easy ways to 
> deal with this.

I forgot to mention a system that works almost like the recipe I gave is the 
SQLSoup extension, you might like it a lot:

http://www.sqlalchemy.org/docs/reference/ext/sqlsoup.html



> 
>> 
>> This presents a maintenance issue I would like to avoid.  So I tried
>> using 'meta.reflect(bind=engine)' which does indeed read all my tables
>> in without the maintenance issues.  However it creates generic Table()
>> classes with no interface additions for the columns. This makes my
>> queries basic SQL with some added sqlalchemy calls to get the table
>> and dereference the columns.  Also not desirable.
> 
>> 
>> I believe this is due to the fact that Sqlalchemy chooses to modify
>> the class definitions on reflection as opposed to class instances.  
> 
> I am assuming there is a breakdown of terminology occuring here.   The 
> reflection process produces instances of the Table object with contained 
> Columns.  These are not classes, they are instances.  The classes in use are 
> sqlalchemy.schema.Table and sqlalchemy.schema.Column, and these do not change 
> nor are they dynamically extended.    There is also no "dereferencing" step 
> I'm aware of unless you are referring to the present of the Column objects on 
> the .c. collection.   The table metadata produced by the MetaData object has 
> no knowledge of the ORM or the declarative extension, but the ORM builds upon 
> these constructs.
> 
> It sounds like you'd like a reflection process that produces 
> declarative-bound ORM classes, not Table instances.  The recipe below 
> achieves this, by generating a new declarative class for each Table reflected 
> by the metadata.
> 
> from sqlalchemy import *
> from sqlalchemy.orm import *
> from sqlalchemy.ext.declarative import declarative_base
> 
> def declared_classes_for_tables(Base, engine):
>     result = {}
>     Base.metadata.reflect(engine)
>     for table in Base.metadata.tables.values():
>         cls_ = type(str(table.name), (Base,), {'__table__':table})
>         result[cls_.__name__] = cls_
>     return result
> 
> # demo
> if __name__ == '__main__':
>     engine = create_engine('sqlite://', echo=True)
>     metadata = MetaData()
>     for name in ('peas', 'carrots', 'celery', 'brocolli'):
>         Table(name, metadata,
>             Column('id', Integer, primary_key=True),
>             Column('data', String(50))
>         )
>     metadata.create_all(engine)
>     
>     # now reflect the database into classes
>     Base = declarative_base()
>     classes = declared_classes_for_tables(Base, engine)
>     
>     sess = sessionmaker(engine)()
>     sess.add_all([
>         classes['carrots'](data='carrot1'),
>         classes['peas'](data='pea1')
>     ])
>     
>     print sess.query(classes['carrots']).all()
>     print sess.query(classes['peas']).all()
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to