Michael,

thanks for your reply, which states what I expected is going on behind
the scenes. However, for the case I mentioned (the "env" field that
the mapper could not find anymore) I can say for certain that this
particular table was not changed at all by DDL. This really puzzled
me, obviously. I actually have to admit that I have no proof that
schema changes trip the application. It's just an observation I made
every time this has happened. It may well be that there's something
else happening every time the schema changes. Is there actually any
way at all a mapper could "forget" about a column when there's no DDL
change to the table?

I should really try and reproduce the problem first in a controlled
environment to be sure I'm isolating the correct problem.

Cheers,
Sven

On Oct 11, 6:12 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Oct 11, 2010, at 11:17 AM, Sven A. Schmidt wrote:
>
>
>
>
>
> > Hi,
>
> > I've got an issue which pops up from time to time with an SQLAlchemy
> > based webservice application and it revolves around schema changes
> > happening while an engine with autoload=True has been instantiated and
> > is being used to start sessions.
>
> > What happens is that someone on the team will make a schema change
> > (mostly backwards compatible, for example increasing the varchar size
> > of a field) without asking for a restart of the webservice. Subsequent
> > calls to the webservice will fail with quite obscure (i.e. seemingly
> > unrelated) error messages. For example, I've seen errors like the
> > following:
>
> > Error: type object 'AppEnvRpe2Table' has no attribute 'env'
>
> > (AppEnvRpe2Table is the object mapped to an sqlalchemy.Table.) First I
> > thought someone had dropped the column (they'd actually do that...)
> > but to my surprise the given table did have a column 'env' (and it did
> > since the start). A restart of the service (i.e. reload of the schema)
> > always fixed this kind of problem, which led me to believe it's
> > related to the engine's internal representation of the schema somehow
> > conflicting with updates in the database even when it's in places that
> > aren't used in the particular query being executed.
>
> > Obviously, it's never a good idea to change the schema when a process
> > is running, but in this case I have no control over the changes being
> > made. I've warned about it but it happens anyway and then on next
> > execution of the webservice a crash results. Sometimes quite a bit of
> > time between the schema change and the calling of the webservice can
> > occur so it's not always immediately clear that it was the schema
> > change that caused the problem. (I'm actually thinking of keeping this
> > issue around because I've won lots of beers when they complained about
> > crashes and it turned out to be their fault to begin with but you can
> > drink only so much... ;)
>
> > So that being the set-up, I'm wondering what I can do to remedy the
> > situation. Things I considered:
>
> > - Re-create the engine on every request. Bad, because it increases run-
> > time for every request and most of the time (i.e. when there was no
> > schema change) it is unnecessary. There are quite a few tables in the
> > schema and autoload time is not negligible.
>
> > - Re-create the engine after a schema change. The question is how do I
> > programmatically notice a schema change? I can't rely on exceptions,
> > because there's not a predictable error popping up when this occurs.
>
> > - Catch errors and retry with new engine instance. The problem is that
> > I'd have to catch pretty much any exception (unpredictable errors, see
> > above), and I'd possibly obscure other issues by doing so.
>
> > - Get an extra liver and just suffer the consequences...
>
> > Any ideas greatly appreciated!
>
> > PS: This is sqlalchemy 0.5.8 and I cannot easily update to 0.6 if that
> > should be required.
>
> Increasing the size of a VARCHAR field in the DB will never have any effect 
> on the app as it runs.   If the field has already been reflected, your 
> application will never see the new value.   If the field has not yet been 
> reflected, your app, upon reflecting the table, will see the new size, stick 
> it in the type object, and never look at it again.   So that's not the source 
> of the issue.
>
> The only thing that would cause any issues are renames of columns/tables, or 
> drops of columns/tables that are mapped.  If that is the source, then the 
> problem has little to do with engines, and is more about mappers.   If your 
> table has an "env" column, then the mapper will apply an "env" attribute to 
> the mapped object.   The "no env attribute" error would therefore be a side 
> effect of some other schema/mapping mismatch.
>
> The simple fact is, if you map a class A to a table "a", a plain query(A) 
> will issue a SELECT for all columns explicitly:
>
>         select x as a_x, y as a_y, z as a_z from a
>
> If a DBA logs in and drops column "Y" from the database, your app is now 
> broken, end of story.
>
> It's not reasonable to expect the application to gracefully handle the 
> removal of columns upon which the application has been constructed to rely 
> upon.    If you are constructing mappings using autoload=True then mapping, 
> in effect the construction of your mappings is ad-hoc, and if your app is 
> constructed in such a way such that mappings are created sometime after the 
> app starts up, then the construction of the mappings is random.
>
> If you truly want to be unaffected by columns being dropped, you need to 
> ensure your application never has awareness of those columns.   You do this 
> using either hardcoded Table metadata, no autoload, which don't include 
> columns that may be dropped, or you can apply "include_properties" / 
> "exclude_properties" to your mappers, again ensuring that no columns which 
> may be dropped are mapped in any way.
>
>
>
>
>
> > --
> > 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 
> > athttp://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