如何使用 SQLAlchemy 插入数据

How to insert data with SQLAlchemy

我在使用 SQLAlchemy 将数据插入数据库时​​遇到问题。 我将 scoped_session 与上下文管理器(class 实现)一起使用:

class Session:
    def __init__(self):
        pass

    def __enter__(self):
        engine = create_engine("sqlite:///test.db", echo = True)
        self.connection = engine.connect()
        self.session = scoped_session(\
                sessionmaker(\
                autocommit=True,\
                autoflush=False,\
                bind=engine))
        return self.session

    def __exit__(self, type, value, traceback):
        self.session.close()
        self.connection.close()

我的插入函数:

def insert_value(a, b, c)
    with db_session() as db:
        db.add(Value(a = a, b = b, c = c))

即使在提交之后,该值也没有正确添加到数据库中,但出于某种原因,它可以与 query().filter().update().

一起使用

db.add() 不产生任何日志,SQLAlchemy 的文档也没有帮助。

编辑: 问题是 db.add() 作为 select,更新和删除操作是通过查询完成的(例如 db.query().all()db.query().values()db.query().delete())并且工作正常。

编辑 2: 关于我如何实例化 class 和 engine

的一些精确度
Base = declarative_base()

class Value(Base):
    __tablename__ = "values"

    a = ...
    b = ...
    c = ...

Base.metadata.create_all(create_engine(...))

https://docs.sqlalchemy.org/en/14/orm/session_transaction.html

根据上述文档,我猜 autocommit 已被弃用。他们现在有一个 session.begin() 方法用于自动提交。

所以你可以这样使用它:

with db_session.begin():
      foo

我解决了这个问题。

我认为问题的原因是:

  • 自动提交的使用
  • 我启动了引擎两次,一次用于会话,一次用于基础 类。
engine = create_engine(...) // Initiated once and for all

Base = declarative_base()

class Value(Base):
    __tablename__ = "values"

    a = ...
    b = ...
    c = ...

Base.metadata.create_all(engine)

class DbSession:
    def __init__(self):
        pass

    def __enter__(self):
        self.connection = engine.connect() // Reuse the engine instead of creating a new one
        self.session = scoped_session(\
                sessionmaker(\
                autocommit=False,\
                autoflush=False,\
                bind=engine))
        return self.session

    def __exit__(self, type, value, traceback):
        self.session.commit()
        self.session.close()
        self.connection.close()


def insert_value(a, b, c):
    with DbSession() as db:
        db.add(Value(a = a, b = b, c = c))