繁体   English   中英

如何正确构造SQLAlchemy(声明式)python项目及其单元测试

[英]How to correctly structure SQLAlchemy (declarative style) python project and it`s unittests

我正在为某些Web应用程序开发大型后端。 这是我的第一个python和SQLAlchemy项目,所以我对某些事情感到困惑。 与python相比,它被Java编程工具和IDE宠坏了(无论如何,我在eclipse中使用pydev)。 我需要有关如何构建项目和编写测试的帮助。 我先描述一下情况。

在PyDev中,我将项目命名为“ ProjectName”,并在下面显示了当前的文件夹/包和文件结构。

  • 项目名
    • 项目名
      • __init__.py
      • some_package
        • __init__.py
        • 傻瓜
        • 巴比
    • 测试
      • 单元测试
        • __init__.py
        • some_package
          • __init__.py
          • TestFoo.py
          • TestBar.py
      • 负载测试
      • integration_tests
      • __init__.py

我在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类的单元测试?

因此,再次提取最重要的问题:

  1. 如何构建使用SQLAlchemy声明式样式并正确进行单元测试的python项目。 顺便说一句,我在Foo和Bar中有很多与数据库交互的类方法,在它们各自的类的上下文中,我希望可以吗?
  2. 在何处存储基本声明性类,以及如何在整个项目中正确使用它,以及如何在项目中的任何位置提取所有数据库模式(我在类中声明性定义)并使用它?
  3. 如何最好地使用带有SQLAlchemy的单元测试并一次运行多个单元测试?
  4. 如果您有其他建议,可以随时添加吗?

非常感谢你的帮助。

快速答案(时间紧,抱歉):使用单个MetaData实例,而不是同时为Foo和Bar使用一个实例。 通常,多个MetaData实例是您几乎不需要的高级技巧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM