Open pedersen opened 12 years ago
Original Author: pedersen, Original Timestamp: 2011-03-10 03:42:54.038000
Original Body: Hello,
In tg1 I use mapper in model.py to do a reflect tables from database to SqlAlchemy (SA). With this relflect don't needs create all columns in model again, because talbles already created in database. But in TG2 I try the same, like as working in tg1, but not works for me.
In tg1 I was do for example in model.py:
cadcar_table = Table('cadcar',metadata, autoload=True, schema="car")
class Cadcar(object):
pass
mapper(Cadcar, cadcar_table)
But this (reflect) not works in tg2. I Would like know how I do this in tg2, like as in tg1.
Thank you!
There are some hints in model.py for how to do this, but basically you need to do the refelection inside init_model so that it can be deferred to later in the application load process when the SQLAlchemy metadata is setup for you.
If you are still having trouble, could you post a traceback and link to it here so we can try to help you better?
Thank!
This seems like something we need to clarify rather than fix.
There's even an example of how to do this in quickstart now.
I'm reopening because I just stumbled upon this error.
I'm using the following as example code.
#1 metadata.reflect(bind=engine)
from sqlalchemy import Table
global Site
class Site(DeclarativeBase):
#1 __table__ = metadata.tables['site']
#2 __table__ = Table('site',metadata,autoload=True)
#3 __table__ = Table('site',metadata,autoload=True,autoload_with=engine)
1- the first table declaration works (and the reflect all at line1) 2- This line does not works (this is the example in quickstart) 3- This line does work
Reflection made with a mysql database.
Original Author: pedersen, Original Timestamp: 2012-08-24 01:34:45.404000
Original Body: - version: 2.1.0 --> 2.1.5
I'm wondering ... why does this have to be in the init_model method to begin with. Yes, as the code is set up it has to be because of the engine you'd need.
I know a lot of people are really fond of re-coding their database schema in python, but if you have an existing database scheme with lots of tables and relations (in my case 214 tables), having to do everything with global variables in the init_model function is very counter-productive.
At that point you can either re-code the entire database schema, drop turbogears to begin with, or put everything in a megabyte sized init_model function.
I'll go dig into the app config code. If the engine was available earlier it would allow to use several modules for database mapping and auto-reflection - which would make migrating a large app from TG1 or any other pre-existing database application a lot easier.
Using DeferredReflection avoids the need of an engine being available when declaring classes, so you can declare them where you prefer: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#using-reflection-with-declarative
Amol: thanks for the heads up. That's a useful feature!
Actually, after I wrote my earlier comment, I dug into the app_config code and found that it's pretty easy to eliminate the entire "init_model" function and have the engine ready to go when the model is first imported. Most changes are in the app_cfg.py file, but what I don't like about my solution is that it requires 2 small changes in the tg code. It's always bad to modify the core because it makes upgrading a lot harder. Therefor the deferred reflection is obviously the better way.
This issue existed in Trac. The original can be viewed at http://trac.turbogears.org/ticket/2213
This issue existed on SourceForge. The original can be viewed at https://sourceforge.net/p/turbogears2/tickets/13