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

如何正确构造SQLAlchemy(声明式风格)python项目及其单元测试,python,unit-testing,testing,sqlalchemy,Python,Unit Testing,Testing,Sqlalchemy,我正在为一些web应用程序开发大型后端。这是我的第一个python和SQLAlchemy项目,所以我对一些事情感到困惑。与python相比,Java编程工具和IDE有点破坏了它(无论如何,我在eclipse中使用pydev)。我需要有关如何构建项目和编写测试的帮助。我先描述一下情况 在PyDev中,我将我的项目命名为“ProjectName”,下面我展示了我当前的文件夹/包和文件结构 项目名称 项目名称 __初始值 一些包装 __初始值 福比 巴比 测验 单元测试 __初始值 一

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

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

  • 项目名称
    • 项目名称
      • __初始值
      • 一些包装
        • __初始值
        • 福比
        • 巴比
    • 测验
      • 单元测试
        • __初始值
        • 一些包装
          • __初始值
          • TestFoo.py
          • TestBar.py
      • 负荷试验
      • 集成测试
      • __初始值
我在SQLAlchemy中使用声明式风格。Foo和Bar是一些类,比如Foo扩展了SQLAlchemy声明性Base,Bar扩展了Foo。在's_uuuinit_uuuuuu.py中的'projectname.some_package'下,我有以下代码:

engine = create_engine('mysql+mysqldb://user:pass@localhost:3306/SomeDataBase', pool_recycle=3600)
Session = sessionmaker(bind=engine)
Base = declarative_base()
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()
所以,Foo导入这个基并扩展它,Bar导入Foo并扩展它。我的第一个问题是,我是否应该将Base存储在这个_uinit__uuuuy.py中,并像我从这两个类开始时那样使用它?这个create_引擎只是临时的,我想要配置文件并从那里加载它的设置,怎么做?我应该在哪里调用Base.metadata.create_all(),以便它可以一次创建所有数据库表

接下来,在测试类中,例如在TestFoo中,我有以下代码:

engine = create_engine('mysql+mysqldb://user:pass@localhost:3306/SomeDataBase', pool_recycle=3600)
Session = sessionmaker(bind=engine)
Base = declarative_base()
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)
是:

当我运行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)
/usr/local/lib/python2.7/dist-packages/sqlalchemy/ext/declarative.py:1336:SAWarning:类名“Foo”已在该声明性库的注册表中,映射到
_as_声明性(cls,classname,cls.\uu dict\uuuuu)
/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/default.py:330:警告:字段“id”没有默认值
cursor.execute(语句、参数)
这里有什么问题?我试着用nose和pydev跑步者运行测试,但得到了相同的错误。然后我尝试在单元测试下的某个_包中的uuu init_uuuu.py中移动数据库表创建,但无法使其工作。另外,我对python导入的工作原理感到困惑。例如,如果我在TestBar类中添加Foo导入,我也会得到类似于我已经显示的错误。如何一次运行多个测试SQLAlchemy类的单元测试

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

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

  • 非常感谢您的帮助。

    快速回答(抱歉,时间不够):使用单个元数据实例,而不是同时为Foo和Bar使用一个元数据实例。通常,多个元数据实例是一个高级技巧,您几乎不需要它。

    在以下位置有一个推荐的单元测试模式:。对于结构化应用程序的例子,你可以看看,我也想知道这个问题的答案。我在使用时遇到了问题,最终需要将所有sqlalchemy代码转储到一个文件中,或者它无法正常工作。在某个中心文件中放置一个基,如model/meta.py,然后每隔一个包“从model.meta导入基”导入。通常不需要多个基类。