On Jan 28, 2013, at 10:35 AM, Scott Sadler wrote: > Hi Micheal, > > I tried the before_parent_attach event but it passes the column as the > parent, and column.table is still None at that point.
oh right, so in this case it might require that you apply the event to Columns, then check the type for "Enum" and then do the schema transfer. > Also I'm not sure if that would work since events can be replicated to copies > of objects but the event handlers themselves will still refer to the original > objects, that's not ringing a bell for me. when an event is called, the object that is dispatching sends itself in as the target. So in general you get the correct target for an event. If you're referring to the fact that the "Enum" type has not been copied, that's a separate issue which I mentioned probably needs some extra feature. > > The before_parent_attach event works if you register it on the column: > > for table in metadata.tables.values(): > for _, column in dict(table.columns).items(): > if isinstance(column.type, postgresql.ENUM): > event.listens_for(column, 'before_parent_attach', > propagate=True)(propagate_schema) > > but you still _have_ to copy the type in Column._construct otherwise the > schemaless instance of the type binds to the before_create event of the new > table. if you're referring to after the copy() takes place, this is true. There's nothing built in for that right now unless we go with the "inherit_table_schema" approach, or something similar. Also after some thought I think the "type" should be copied unconditionally, last night I was confusing the concept of two separate ENUM objects with the fact that if they both have the same name and schema, they still refer to the same database construct. I've added http://www.sqlalchemy.org/trac/ticket/2657 for this. > > Regards > > > > > On Sunday, 27 January 2013 23:10:20 UTC, Michael Bayer wrote: > > On Jan 27, 2013, at 4:42 PM, Scott Sadler wrote: > > > Hi, I wanted to post here since I had to hack around an issue in order to > > use SQLAlchemy with a dynamic Postgres schema, and I wanted to see if > > there's a way I can get the workarounds out of my code. > > > > In my app I'm separating the data by dynamically managing the schemas. The > > basic way this is achieved is: > > > > new_meta = MetaData(schema='newschema') > > for table in old_meta.tables.items(): > > table.tometadata(new_meta) > > new_meta.create_all() > > > > This worked nicely until I tried to use postgresql.ENUM type. The ENUM is a > > first class schema object so it needs to be created separately, but it does > > this by registering an event on the first table it's bound to (doesnt > > transfer to copies) and it doesn't inherit the schema of the table it's > > bound to > > the ENUM type accepts an argument "schema" for this purpose, which is part of > the base sqlalchemy.types.Enum contract: > > Table('mytable', metadata, Column('data', postgresql.ENUM(name='myenum', > schema='someschema')), schema='someschema') > > Whether that schema should automatically be copied from the parent table, I'm > not sure. It would likely be confusing to change it now, though. > > You can affect this result yourself without any subclassing, using the > after_parent_attach event: > > my_enum = ENUM(...) > > @event.listens_for(my_enum, "after_parent_attach") > def associate_schema(target, parent): > target.schema = parent.schema > > http://docs.sqlalchemy.org/en/rel_0_8/core/events.html?highlight=after_parent_attach#sqlalchemy.events.DDLEvents.after_parent_attach > > > Enum also has a create() method of its own, so that you can emit the create > any time: > > mytable.c.data.type.create(engine, checkfirst=True) > > > http://docs.sqlalchemy.org/en/rel_0_8/core/types.html?highlight=enum#sqlalchemy.types.Enum.create > > > as for tometadata() not creating a copy of the type, I can see that being an > issue. The fact that PG has these types created separately implies the use > case of the same type being used for multiple tables, so it's not clear if > tometadata(schema) should unconditionally suggest copying the enum type out > to that schema as well. Both behaviors could potentially be indicated by > adding a new flag to types.Enum called "inherit_table_schema", indicating the > Enum should attach itself to any table and adopt its schema, and also be > copied during a tometadata() operation with the new schema. > > > > > > > > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
