我是否需要使用依赖注入来使用SQLAlchemy?

时间:2017-05-25 16:45:49

标签: python sqlalchemy

我觉得奇怪的是人们不使用依赖注入来管理他们对SQLAlchemy的使用。根据文档,需要对表的引用来执行像insert这样的db操作,但只有在创建表后才能获得对表的引用!

这意味着db连接,db操作和表声明必须在同一个文件中完成:

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> conn = engine.connect()
>>> metadata = MetaData()
>>> users = Table('users', metadata,
...     Column('id', Integer, primary_key=True),
...     Column('name', String),
...     Column('fullname', String),
... )
>>> ins = users.insert()
>>> result = conn.execute(ins)

根据上面的snippet,需要conn连接对象,users表对象和ins表达式对象来执行与数据库的完整事务。除非使用某种形式的依赖注入,否则这三个必须位于同一个文件中。

人们如何构建代码以使其易于管理?

2 个答案:

答案 0 :(得分:2)

  •   

    需要对表的引用来执行像insert这样的db操作,但只有在创建表后才能获得对表的引用!

    我在这里看不到任何问题,在RDBMS中你也应该创建表来执行其他操作(如CRUD)。

    如果您不想创建Table个对象或mapping,则可以随时执行raw SQL statements

  •   

    这意味着db连接,db操作和表声明必须在同一个文件中完成

    不正确的。我们可以将您的示例重构为单独的modules

    tables.py

    from sqlalchemy import MetaData, Table, Column, Integer, String
    
    metadata = MetaData()
    users = Table('users', metadata,
                  Column('id', Integer, primary_key=True),
                  Column('name', String),
                  Column('fullname', String))
    

    main.py

    from sqlalchemy import create_engine
    
    from tables import users
    
    db_uri = 'sqlite:///'
    engine = create_engine(db_uri)
    users.create(bind=engine)
    conn = engine.connect()
    values = {'name': 'John',
              'fullname': 'Doe'}
    ins = users.insert().values(values)
    result = conn.execute(ins)
    

    因为我们看到表声明在tables.py模块中,而使用连接/事务处于main.py时,我错过了什么?

答案 1 :(得分:2)

你不需要在Python中使用它,你可以将模块导入用作单例,这是大多数人在大多数时间里所做的事情。任何模块级代码都将在导入模块时执行。

但是......对于大型项目来说DI确定很好,不同的层存在于不同的python包中。我使用ZCA(Zope组件架构)作为我所有大型sqlalchemy项目的DI系统,它很棒。它是一堆额外的样板,因此大多数中小型项目都不会受到打扰,但它对于大规模架构来说非常好用,并且具有测试灵活性,易于模拟服务以及只有DI系统负责交换您的服务。

就个人而言,我创建了一个充当会话工厂的模型引擎的组件,并使用zca查找来获取它。我还将模型类注册为ZCA实用程序,并通过接口查找获取它们,以便其他可重用组件可以实现为不同模型类的zca适配器。 Zope世界的很多框架都使用它:Pyramid,Plone,Grok,BlueBream,Twisted。

我喜欢DI,但YMMV,其他人讨厌样板!