我正在编写 Python 应用程序以使用 SQLAlchemy 在 Postgres 数据库上运行。在settings.py
DATABASE = {
'drivername': 'postgres',
'host': 'xyz.com',
'port': '5432',
'username': 'user',
'password': 'pass',
'database': 'db_dev'
}
然后我创建了一个 db_connection.py
,其中包含一个创建连接的方法。
from sqlalchemy import *
from sqlalchemy.engine.url import URL
from . import settings
def get_engine():
return create_engine(URL(**settings.DATABASE))
我想要另一个模块 db_ops.py
具有所有数据库操作 func1
, func2
方法并在主应用程序中调用它们模块
engine = db.connection.get_engine()
db_ops.func1()
db_ops.func2()
这意味着我需要将 engine
作为参数传递给这些方法。
func1(engine)
func2(engine)
不知何故,我不喜欢将数据库连接作为方法参数的想法。有更好的方法吗?
最佳答案
引擎
不是连接。您可以将其视为连接池。通常使用引擎最自然的方式是将其置于全局级别。在你的情况下,你可以把它放在 db_connection.py
中:
from sqlalchemy import *
from sqlalchemy.engine.url import URL
from . import settings
engine = create_engine(URL(**settings.DATABASE))
然后,您可以将其导入到您的db_ops
模块中:
from db_connection import engine
def func1():
engine.execute(...)
但是,对于一系列相关查询,您可能希望在单个事务中执行它们,这需要绕过实际连接:
with engine.begin() as connection:
func1(connection)
func2(connection)
为了解决这个问题,我们有一个概念 scoped_session
(同样,也是在全局层面):
engine = create_engine(URL(**settings.DATABASE))
Session = scoped_session(sessionmaker(bind=engine))
每次 Session
被调用时,它会检查当前线程是否已经存在一个 session ,如果没有就创建它,从而避免传递连接的需要:
from db_connection import Session
def func1():
Session.execute(...)
在db_ops
函数的调用者中:
try:
func1()
func2()
Session.commit()
finally:
Session.remove()
关于python - 将数据库连接作为参数传递给方法是一种好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47142870/