Reflection tables on model for tg2. #9

Open
pedersen opened this Issue Sep 24, 2012 · 5 comments

Projects

None yet

3 participants

@pedersen
Member

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

@pedersen
Member

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.

@pedersen
Member

Original Author: pedersen, Original Timestamp: 2012-08-24 01:34:45.404000

Original Body: - version: 2.1.0 --> 2.1.5

  • milestone: 2.2.0 --> 2.3.0
@ucs0802
ucs0802 commented Dec 22, 2013

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.

@amol-
Member
amol- commented Dec 24, 2013

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

@ucs0802
ucs0802 commented Dec 24, 2013

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment