LateCoder
LateCoder

Reputation: 2283

SQLAlchemy not behaving correctly after table dropped

I have some test code that creates tables and drops them for each test case. However, all tests fail after the first one because I am relying on code that uses sa.Table() for something first and only creates the new tables if calling that method errors with NoSuchTableError. However, this error is not thrown after the tables are first dropped, even though the engine correctly reports that they do not exist, and so they are not created again.

I've reproduced this behavior as follows:

>>>import sqlalchemy as sa
>>>from sqlalchemy import *
>>>m = MetaData()

The tables don't exist, so calling sa.Table here errors as expected:

>>>t = sa.Table('test', m, autoload_with=eng) 
...
NoSuchTableError: test

But if I create the table and then drop it, sa.Table does not error as expected:

>>>t = sa.Table('test', m, Column('t', String(2)))
>>>m.create_all(eng)
>>>eng.has_table('test')
True
>>>t = sa.Table('test', m, autoload_with=eng)
>>>eng.execute('drop table "test" cascade')
<sqlalchemy.engine.result.ResultProxy at 0x106a06150>
>>>eng.has_table('test')
False
>>>t = sa.Table('test', m, autoload_with=eng)

No error is thrown after that last call to sa.Table, even though the table does not exist.

What do I need to do to get sa.Table() to correctly error after the tables have been dropped? The engine object I am passing to it knows that the tables do not exist, but is there something else I need to do, like refreshing/reconnecting somehow, so that I get the expected behavior?

Upvotes: 1

Views: 361

Answers (1)

LateCoder
LateCoder

Reputation: 2283

Turns out I need to refresh the MetaData object (create a new one) each time I call sa.Table if I expect the schema to change. This solves the problem.

Upvotes: 3

Related Questions