Server defaults appear to be handled incorrectly in some cases (looks
like for string values) in versions 0.6 and 0.7. The code works in
0.5.

I run into this with sqlite, and don't have access other databases
right now.
Test case (code below):
1. create a table with server side default value (I am using DEFAULT
'A B' for illustration)  by executing a DDL statement on a connection.
2. reflect that table into a metadata instance
3. drop the table
4. use metadata to recreate table

This should recreate the same table, and will do so in 0.5. In 0.6 and
0.7 the default is rendered as DEFAULT A B without the single quote
enclosing 'A B' leading to an OperationalError exception. The
interesting thing is that if step 1 is done by creating a Table
instance directly in the metadata, then the missing single quotes are
generated correctly. It appears that the root cause is that when
reflecting the table from sqlite (and maybe other databases as well)
the the c.server_default.arg property is missing the single quotes in
0.6+, but the quotes are present in 0.5. I suspect that DDL generation
blindly plugs in whatever is present in c.server_default.arg leading
to the error.

Sample code:
from sqlalchemy import __version__ as sa_ver
print 'SQLAlchemy version:', sa_ver
from sqlalchemy import *

def setup1():
    print '***** Create table with Table class *****'
    e = create_engine('sqlite:///', echo=True)
    meta = MetaData(bind=e)
    dflt_tbl = Table('test_default', meta,
            Column('id', Integer, primary_key=True),
            Column('int_dflt', Integer, server_default=text(str(0))),
            Column('str_dflt', String, server_default=text("'A B'"))
            )
    meta.create_all()
    return meta

def setup2():
    print '***** Create table with external DDL *****'
    e = create_engine('sqlite:///', echo=True)
    meta = MetaData(bind=e)
    e.execute(text("""CREATE TABLE test_default (
     id INTEGER NOT NULL,
     int_dflt INTEGER DEFAULT 0,
     str_dflt VARCHAR DEFAULT 'A B',
     PRIMARY KEY (id)
     )"""))
    meta.reflect()
    return meta

def tryit(meta):
    print '***** Examine / use the metadata *****'
    tbl = meta.tables['test_default']
    for c in tbl.c:
        if c.server_default:
            print '***** Column [%s] has server default [%s]' \
                    % (c.name, c.server_default.arg)
    tbl.drop()
    meta.create_all()

meta = setup1()
tryit(meta)
meta = setup2()
tryit(meta)

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@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