2013-04-19 22 views
7

Próbuję utworzyć nowy logiczną, non-zerowalne kolumny (z domyślnym = true) w tabeli z poniższego skryptu SQL alchemii:Wartość domyślna ignorowane non wartości pustych kolumnie

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) 

Wynika to w dość zaskakujący błędu:

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'() 

o ile mi zrozumieć, sqlalchemy brakuje wartość domyślną, ale nie obejmują default=True! Co jest nie tak?

Odpowiedz

16

Zastosowanie server_default="true", tak:

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

Gdzie default służy do instancji klasy i server_default służy do definicji kolumny bazy danych.

+0

Dzięki! Nie zdawałem sobie sprawy, że 'default' jest po prostu tworzeniem w języku Python sqlalchemy (to jest to, co sqlalchemy * wstawia *, jeśli wartość nie jest podana) i nie ma nic wspólnego z bazową bazą danych. – phihag

+0

Dziwne, czy to nie "Fałsz" (wielkie F) pasuje do składni Pythona? – benjaminz

+0

'server_default' podobnie jak wyrażenie sql, a nie wyrażenie w python http://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.Column.params.server_default – estin