数日前にSQLAlchemyを使い始めたばかりですが、今は誰もが私の髪をゆるめる前に誰かに光を当ててくれることを願っています。unitAlertのSQLAlchemyセッションvoes
unittestを実行すると、以下のスニペットを参照してください。シーケンス内の最初のテストだけが合格です。テストtestPhysicalPrintは正常に動作しますが、NoResultFound例外でtestRecordingItemが失敗します。の行が見つかりませんでした。しかし、テストクラスからtestPhysicalPrintを削除すると、testRecordingItemが機能します。
問題はセッションと関係がありますが、実際にはそれを把握することはできません。誰もが疑問に思う場合
は、セットアップは次のとおりです。
- のPython 3.1(Ubuntuの10.04パッケージ)
- SQLAlchemyの0.7.2(easy_installを:ED)
- のPostgreSQL 8.4.8(Ubuntuの10.04パッケージ)
- PsycoPG2 2.4.2(easy_installed:ED)
Exemple試験:
class TestSchema(unittest.TestCase):
test_items = [
# Some parent class products
PrintItem(key='p1', title='Possession', dimension='30x24'),
PrintItem(key='p2', title='Andrzej Żuławski - a director', dimension='22x14'),
DigitalItem(key='d1', title='Every Man His Own University', url='http://www.gutenberg.org/files/36955/36955-h/36955-h.htm'),
DigitalItem(key='d2', title='City Ballads', url='http://www.gutenberg.org/files/36954/36954-h/36954-h.htm'),
]
def testPrintItem(self):
item = self.session.query(PrintItem).filter(PrintItem.key == 'p1').one()
assert item.title == 'Possession', 'Title mismatch'
def testDigitalItem(self):
item2 = self.session.query(DigitalItem).filter(DigitalItem.key == 'd2').one()
assert item2.title == 'City Ballads', 'Title mismatch'
def setUp(self):
Base.metadata.create_all()
self.session = DBSession()
self.session.add_all(self.test_items)
self.session.commit()
def tearDown(self):
self.session.close()
Base.metadata.drop_all()
if __name__ == '__main__':
unittest.main()
UPDATE
ここで作業コードスニペットです。
# -*- coding: utf-8 -*-
import time
import unittest
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import *
Base = declarative_base()
engine = create_engine('sqlite:///testdb', echo=False)
DBSession = sessionmaker(bind=engine)
class ItemMixin(object):
"""
Commons attributes for items, ie books, DVD:s...
"""
__tablename__ = 'testitems'
__table_args__ = {'extend_existing':True}
id = Column(Integer, autoincrement=True, primary_key=True)
key = Column(Unicode(16), unique=True, nullable=False)
title = Column(UnicodeText, default=None)
item_type = Column(Unicode(20), default=None)
__mapper_args__ = {'polymorphic_on': item_type}
def __init__(self, key, title=None):
self.key = key
self.title = title
class FooItem(Base, ItemMixin):
foo = Column(UnicodeText, default=None)
__mapper_args__ = {'polymorphic_identity':'foo'}
def __init__(self, foo=None, **kwargs):
ItemMixin.__init__(self, **kwargs)
self.foo = foo
class BarItem(Base, ItemMixin):
bar = Column(UnicodeText, default=None)
__mapper_args__ = {'polymorphic_identity':'bar'}
def __init__(self, bar=None, **kwargs):
ItemMixin.__init__(self, **kwargs)
self.bar = bar
# Tests
class TestSchema(unittest.TestCase):
# Class variables
is_setup = False
session = None
metadata = None
test_items = [
FooItem(key='f1', title='Possession', foo='Hello'),
FooItem(key='f2', title='Andrzej Żuławsk', foo='World'),
BarItem(key='b1', title='Wikipedia', bar='World'),
BarItem(key='b2', title='City Ballads', bar='Hello'),
]
def testFooItem(self):
print ('Test Foo Item')
item = self.__class__.session.query(FooItem).filter(FooItem.key == 'f1').first()
assert item.title == 'Possession', 'Title mismatch'
def testBarItem(self):
print ('Test Bar Item')
item = self.__class__.session.query(BarItem).filter(BarItem.key == 'b2').first()
assert item.title == 'City Ballads', 'Title mismatch'
def setUp(self):
if not self.__class__.is_setup:
self.__class__.session = DBSession()
self.metadata = Base.metadata
self.metadata.bind = engine
self.metadata.drop_all() # Drop table
self.metadata.create_all() # Create tables
self.__class__.session.add_all(self.test_items) # Add data
self.__class__.session.commit() # Commit
self.__class__.is_setup = True
def tearDown(self):
if self.__class__.is_setup:
self.__class__.session.close()
# Just for Python >=2.7 or >=3.2
@classmethod
def setUpClass(cls):
pass
#Just for Python >=2.7 or >=3.2
@classmethod
def tearDownClass(cls):
pass
if __name__ == '__main__':
unittest.main()
こんにちは!あなたに感謝します。私はBase.metadata.drop_all()を入れているtearDownで - それは問題のテーブルをドロップしないため、各テスト後にデータを削除しないだろうか? –
あなたは正しいです。しかし何らかの理由で、データは実際には2回目に挿入されません。エンジンに 'echo = True'を設定し、生成されたSQL文を見ると、2回目にデータ行が挿入されないことがわかります。この時点で私は理由を知りません。それでも、オプション1を実装してデータを一度しか作成しないでください(テストしてもそれを削除しないと問題は回避されます)。 – van
setUpでコミットを削除して、セッションがtearDownで閉じられる直前にロールバックを追加した後は、動作します。うーん... –