我遇到了alembic的stamp命令和使用sqlite内存数据库进行测试的一些问题。与基于文件的sqlite dbs完美配合的测试因OperationalError: (OperationalError) no such table
而失败。
我在初始化期间加盖标记以显示数据库是最新的:
def init_db(engine, version):
tables.Base.metadata.create_all(engine)
with engine.begin() as connection:
stamp_alembic(connection)
def stamp_alembic(connection):
from alembic import command
from alembic.config import Config
alembic_cfg = Config('alembic.ini')
alembic_cfg.attributes['connection'] = connection
command.stamp(alembic_cfg, 'head')
我正在将当前连接传递给env.py
as per the cookbook:
def run_migrations_online():
connectable = config.attributes.get('connection', None)
if connectable is None:
# only create Engine if we don't have a Connection
# from the outside
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
我的测试班:
SETTINGS = {'sqlalchemy.url': 'sqlite:///:memory:'}
class TestOperatorUserModel(unittest.TestCase):
def setUp(self):
engine = engine_from_config(SETTINGS, 'sqlalchemy.')
tables.DBSession.configure(bind=engine)
init_db(engine, SETTINGS['version.db'])
transaction.begin()
def tearDown(self):
engine = engine_from_config(SETTINGS, 'sqlalchemy.')
transaction.abort()
tables.Base.metadata.drop_all(engine)
tables.DBSession.remove()
如果我从初始化中删除了戳记,那么测试也可以正常运行。作为一种解决方法,如果engine.url.database
不是':memory:'
,我只会标记数据库,但我想知道问题的真正来源是什么。
环境是Python 2.7.11,SQLAlchemy 0.9.10,alembic 0.8.6和sqlite 2.8.17。