[英]How to correctly structure SQLAlchemy (declarative style) python project and it`s unittests
我正在为某些Web应用程序开发大型后端。 这是我的第一个python和SQLAlchemy项目,所以我对某些事情感到困惑。 与python相比,它被Java编程工具和IDE宠坏了(无论如何,我在eclipse中使用pydev)。 我需要有关如何构建项目和编写测试的帮助。 我先描述一下情况。
在PyDev中,我将项目命名为“ ProjectName”,并在下面显示了当前的文件夹/包和文件结构。
我在SQLAlchemy中使用声明式样式。 Foo和Bar是一些类,例如Foo扩展了SQLAlchemy声明性Base和Bar扩展了Foo。 在它的__init__.py中的“ projectname.some_package”下,我有以下代码:
engine = create_engine('mysql+mysqldb://user:pass@localhost:3306/SomeDataBase', pool_recycle=3600)
Session = sessionmaker(bind=engine)
Base = declarative_base()
因此,Foo导入此Base并对其进行扩展,而Bar导入Foo并对其进行扩展。 我的第一个问题是,是否应该将Base存储在该__init__.py中,并像从这两个类开始一样使用它? 这个create_engine只是临时的,我想拥有配置文件并从那里加载它的设置,该怎么做? 我应该在哪里调用Base.metadata.create_all(),以便它可以一次创建所有数据库表?
接下来,在测试类中,例如在TestFoo中,我有以下代码:
def setUp(self):
#create database tables and session object
self.engine = create_engine('mysql+mysqldb://user:pass@localhost:3306/SomeDatabase', pool_recycle=3600)
Session = sessionmaker(bind=self.engine)
Foo.metadata.create_all(bind=self.engine)
self.session = Session()
def tearDown(self):
#drop all tables and close session object
self.session.close()
meta = MetaData(self.engine)
meta.reflect()
meta.drop_all()
最后,我在该测试类中有一些测试方法,它运行良好。 在TestBar类中的区别是
Foo.metadata.create_all(bind=self.engine)
是:
Bar.metadata.create_all(bind=self.engine)
当我运行TestBar时,它也可以正常运行。 但是,当我选择两个测试类并运行它们时,出现错误:
/usr/local/lib/python2.7/dist-packages/sqlalchemy/ext/declarative.py:1336: SAWarning: The classname 'Foo' is already in the registry of this declarative base, mapped to <class 'projectname.some_package.Foo.Foo'>
_as_declarative(cls, classname, cls.__dict__)
/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/default.py:330: Warning: Field 'id' doesn't have a default value
cursor.execute(statement, parameters)
这里有什么问题? 我试图用鼻子和pydev运行程序运行测试,并得到相同的错误。 然后,我尝试在unit_tests下的some_package中的__init__.py中移动数据库表的创建,但无法正常工作。 另外,我对python导入的工作方式感到困惑。 例如,如果我在TestBar类中添加Foo import,我也会得到与已经显示的错误类似的错误。 如何才能一次运行多个测试SQLAlchemy类的单元测试?
因此,再次提取最重要的问题:
非常感谢你的帮助。
快速答案(时间紧,抱歉):使用单个MetaData实例,而不是同时为Foo和Bar使用一个实例。 通常,多个MetaData实例是您几乎不需要的高级技巧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.