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

base と engine はどちらも models.py で使用され、宣言型アプローチを使用してデータベースを作成します。

test_controller では、モデルと永続性の両方をインポートします。テストを実行すると、tests ディレクトリの下にデータベースが作成されます。更新、挿入、削除などの操作は適切に実行されますが、単体テストを終了する前に、SQLAlchemy は次の例外を発生させます。

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

データベースにアクセスするすべてのメソッドは、常にセッションを閉じます。だから、私はセッションを開いた以上のようです。

同じモデル モジュールを使用して Rails が行うのと同じように、テスト用およびその他の開発用に sqlalchemy データベースをセットアップする方法を知っていますか? 何か案が?

ここにテストコード:

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