2013-04-19 20 views
7

Sto cercando di creare un nuovo booleano, colonna non null (con default = true) in una tabella con il seguente script SQL alchimia:Valore predefinito ignorato nella colonna non annullabile

from sqlalchemy import MetaData, Table, Boolean, Column 

def upgrade(migrate_engine): 
    meta = MetaData(bind=migrate_engine) 
    message_table = Table('message', meta, autoload=True) 
    col = Column('include_signature', Boolean(), default=True, nullable=False) 
    col.create(message_table) 

Questa risultati un errore piuttosto sconcertante:

File "src/adhocracy/migration/versions/061_optional_massmessage_signature.py", line 7, in upgrade 
    col.create(message_table) 
    File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/schema.py", line 528, in create 
    engine._run_visitor(visitorcallable, self, connection, **kwargs) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 2302, in _run_visitor 
    conn._run_visitor(visitorcallable, element, **kwargs) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1972, in _run_visitor 
    **kwargs).traverse_single(element) 
    File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 53, in traverse_single 
    ret = super(AlterTableVisitor, self).traverse_single(elem) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/sql/visitors.py", line 106, in traverse_single 
    return meth(obj, **kw) 
    File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/databases/sqlite.py", line 75, in visit_column 
    super(SQLiteColumnGenerator,self).visit_column(column) 
    File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 101, in visit_column 
    self.execute() 
    File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 42, in execute 
    return self.connection.execute(self.buffer.getvalue()) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1449, in execute 
    params) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1628, in _execute_text 
    statement, parameters 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1698, in _execute_context 
    context) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1691, in _execute_context 
    context) 
    File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py", line 331, in do_execute 
    cursor.execute(statement, parameters) 
sqlalchemy.exc.OperationalError: (OperationalError) Cannot add a NOT NULL column 
with default value NULL '\nALTER TABLE message ADD include_signature BOOLEAN NOT NULL'() 

per quanto ho capito, SQLAlchemy manca un valore di default, ma ho incluso default=True! Cosa c'è di sbagliato qui?

risposta

16

Usa server_default="true", come quella:

col = Column('include_signature', Boolean(), default=True, 
      server_default="true", nullable=False) 

Dove default viene utilizzato per l'istanza di classe e server_default viene utilizzato per la definizione colonna del database.

+0

Grazie! Non mi rendevo conto che "default" è solo una creazione di sqlalchemy basata solo su Python (è ciò che sqlalchemy * inserisce * se il valore non viene fornito) e non ha nulla a che fare con il database sottostante. – phihag

+0

Così strano, non si suppone che sia 'False' (maiuscola F) per abbinare la sintassi python? – benjaminz

+0

'server_default' come espressione sql e non un'espressione python http://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.Column.params.server_default – estin

Problemi correlati