我觉得奇怪的是人们不使用依赖注入来管理他们对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
表达式对象来执行与数据库的完整事务。除非使用某种形式的依赖注入,否则这三个必须位于同一个文件中。
人们如何构建代码以使其易于管理?
答案 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,其他人讨厌样板!