5

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

model/
  models.py
controller/
  controller.py
persistence/
  persistence.py
test/
  test_controller.py

在 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

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

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

DetachedInstanceError: Instance <Account at 0x945378c> is not bound to a Session;   
attribute refresh operation cannot proceed

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

您知道如何设置 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()

并且,在 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)

提前致谢。

4

0 回答 0