如何设置用于测试和开发的 SQLAlchemy 数据库?

Edu*_*pes 5 python unit-testing sqlalchemy

我的项目中有以下文件结构:

model/
  models.py
controller/
  controller.py
persistence/
  persistence.py
test/
  test_controller.py
Run Code Online (Sandbox Code Playgroud)

在persistence.py中,我有一段代码:

from sqlalchemy import *
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm.session import sessionmaker

engine = create_engine("sqlite:///database.db", echo=True)
BASE = declarative_base(engine)

def get_session():
     engine = create_engine("sqlite:///database.db", echo=False)
     Session = sessionmaker(bind=engine)
     session = Session()
     return session
Run Code Online (Sandbox Code Playgroud)

在models.py 中使用Base 和engine 来使用声明式方法创建数据库。

在 test_controller 中,我导入了模型和持久性。当我运行测试时,会在测试目录下创建一个数据库。更新、插入、删除等操作执行良好,但在完成单元测试之前 SQLAlchemy 引发以下异常:

DetachedInstanceError: Instance <Account at 0x945378c> is not bound to a Session;   
attribute refresh operation cannot proceed
Run Code Online (Sandbox Code Playgroud)

访问数据库的所有方法总是关闭会话。所以,似乎我打开的不仅仅是会话。

你知道我如何设置一个 sqlalchemy 数据库用于测试和其他开发,就像 Rails 使用相同的模型模块一样?任何的想法?

这里的测试代码:

from model import Account

engine = create_engine("sqlite://database-test.db", echo=True)
BASE = declarative_base(engine)
BASE.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

def delete_account(account):
  if account:
    session.delete(account)
    session.commit()
    session.flush()
    session.close()

class TestBankController(unittest.TestCase):


  def test_insert_bank_twice(self):
    controller = Account()
    bank = Account('TestAcct')
    controller.create_account(bank)
    try:
        print "tentando inserir repetido"
        bank2 = BankAccount("TestAcct")
        controller.create_account(bank2)
        assert False == True
    except ApplicationException:
        print "ok"


if __name__ == '__main__':
   unittest.main()
Run Code Online (Sandbox Code Playgroud)

并且,在model.py中我有以下内容:

 engine = create_engine("sqlite:///database.db", echo=True)
 BASE = declarative_base(engine)

 class Account(BASE):
   __tablename__ = "accounts_tb"
   id = Column(Integer, Sequence('account_iq_seq'), primary_key=True)
   name = Column(String(250))
   agency = Column(String(40))
   number = Column(String(40))
   initial_balance = Column(Integer)

BASE.metadata.create_all(engine)
Run Code Online (Sandbox Code Playgroud)

提前致谢。