On Jul 28, 2014, at 5:54 PM, Luca Clementi <luca.cleme...@gmail.com> wrote:
> Hi, > I am trying to use my ORM mapping definitions to create my database > schema and I'm looking at the defaults values. > > Apparently when I defined a column, if I use default_server='value' it > will get into the DDL for my DB, but then my object instances will not > have a default value when I instantiate them. > > While if I use the default=value it will be used in my instances to > set a default but it will not be used when creating the DDL for my DB. > > So basically to define a default I have to use both: > default=1024, default_server='1024' > or > default=None, default_server=text('NULL') > > Is this correct or I am missing something? > > Why for simple values (like number) default is not enough? the "default" that you put on a Column() object isn't copied into your ORM object until it is flushed. If the column instead specifies a server_default, the ORM object will also be able to see this value after the flush(), it just requires that the database either emit a SELECT for this value, or it can get it via RETURNING, but it will do this automatically. In either case, post-flush you should see the value on your object, pre-flush you will not. There should never be a need to have both "default" and "server_default". A simple case we can see the "post-select": from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) data = Column(Integer, server_default="10") e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) sess = Session(e) a1 = A() sess.add(a1) sess.flush() assert a1.data == 10 then, to get the server_default via RETURNING, we can use a supporting DB like Postgresql and add "eager_defaults": class A(Base): __tablename__ = 'a' __mapper_args__ = {'eager_defaults': True} id = Column(Integer, primary_key=True) data = Column(Integer, server_default="10") # ... e = create_engine("postgresql://scott:tiger@localhost/test", echo=True) we see in the SQL log: INSERT INTO a DEFAULT VALUES RETURNING a.id, a.data now as far as the feature of having the value present *before* a flush, that isn't available automatically right now. you can, as i just told someone else earlier today (see previous email thread), use an init() event and iterate through the Table metadata to find these defaults and set them up. But SQLAlchemy right now doesn't really want to be concerned with parsing what you put in server_default; if you say "server_default='3'", it's just the number three, but even to determine that it's a constant and not some SQL expression we can't evaluate, requires parsing and guessing, and we'd rather not get into that. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.