On Jul 5, 2010, at 9:10 AM, Chris Withers wrote:
> Chris Withers wrote:
>> Hi All,
>> I'm looking to use:
>> http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything
>> Sadly, the recipe uses hard-coded sql which doesn't work with MySQL.
>> I'd like to change it so that it's database-agnostic like the rest of
>> SQLAlchemy.
>> My hunting has lead me to:
>> http://www.sqlalchemy.org/docs/reference/sqlalchemy/schema.html#sqlalchemy.schema.DropConstraint
>> ...but I'm not sure how to plumb that in given that the recipe only
>> provides a constraint name and table name, not the requisite objects.
>
> Well, my current attempt is:
>
> from sqlalchemy.engine import reflection
> from sqlalchemy.schema import (
> MetaData,
> Table,
> DropTable,
> ForeignKeyConstraint,
> DropConstraint,
> )
>
> conn = engine.connect()
>
> # the transaction only applies if the DB supports
> # transactional DDL, i.e. Postgresql, MS SQL Server
> trans = conn.begin()
>
> inspector = reflection.Inspector.from_engine(engine)
>
> # gather all data first before dropping anything.
> # some DBs lock after things have been dropped in
> # a transaction.
> metadata = MetaData()
>
> tbs = []
> for table_name in inspector.get_table_names():
> fks = []
> for fk in inspector.get_foreign_keys(table_name):
> fks.append(
> ForeignKeyConstraint(
> columns=fk['constrained_columns'],
> refcolumns=fk['referred_columns'],
> name=fk['name'],
> )
why don't you create a ForeignKeyConstraint that only has the "name" field ?
DropConstraint doesn't need anything more than just the name.
> )
> t = Table(table_name,metadata,*fks,
> autoload=True,autoload_with=engine)
also here, again we only need a name. Make yourself a fake table:
t = Table(table_name, metadata, Column('dummy', Integer))
> tbs.append(t)
> for fkc in fks:
> conn.execute(DropConstraint(fkc,cascade=True))
>
> for table in tbs:
> conn.execute(DropTable(table))
> With the above, I did suffer with the following a few times:
>
> sqlalchemy.exc.InvalidRequestError: Table 'some_table' is already defined for
> this MetaData instance. Specify 'useexisting=True' to redefine options and
> columns on an existing Table object.
>
> This doesn't make sense, assuming inspector.get_table_names() only returns
> each table name once... Which it does, right?
that's because you're reflecting the tables, which also reflects their related
tables.
--
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].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.