プロジェクトには次のファイル構造がありました。
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)
前もって感謝します。