1

I am receiving an AttributeError: __enter__ with the following. This is related to with Session(engine) as session:

from sqlalchemy import create_engine
from sqlalchemy import text
from sqlalchemy.orm import Session
from sqlalchemy import MetaData
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy import ForeignKey

engine = create_engine("sqlite+pysqlite:///:memory:", echo=True)

with engine.connect() as conn:
    conn.execute(text("CREATE TABLE some_table (x int, y int)"))
    conn.execute(text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),[{"x": 1, "y": 1}, {"x": 2, "y": 4}])

with engine.begin() as conn:
    conn.execute(text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),[{"x": 6, "y": 8}, {"x": 9, "y": 10},
    {"x": 11, "y": 12}, {"x": 13, "y": 14}])

with engine.connect() as conn:
    result = conn.execute(text("Select x,y From some_table"))
    for x, y in result:
        print(f"x:{x} y:{y}")

stmt = text("SELECT x, y FROM some_table WHERE y > :y ORDER BY x, y").bindparams(y=6)

with Session(engine) as session:
    result = session.execute(stmt)
    for row in result:
        print(f'x: {row.x}  y: {row.y}')

I am using the SQLAlchemy version that is included with Anaconda 1.3.23.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
AndyB
  • 29
  • 1
  • 4

1 Answers1

3

Running the session construction / close process via context manager like so:

engine = create_engine(...)
Session = sessionmaker(bind=engine)

with Session() as session:
    session.add(something)
    session.commit()

Is not supported on SQLAlchemy < 1.4.

If your version of SQLAlchemy is e.g. 1.3.x, you should do instead:

engine = create_engine(...)
Session = sessionmaker(bind=engine)

session = Session()
session.add(something)
session.commit()

If you really want to use a context manager, and at the same time you need to use SQLAlchemy < 1.4, you can use the following approach (copied from the SQLAlchemy docs):

### another way (but again *not the only way*) to do it ###

from contextlib import contextmanager

@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = Session()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()


def run_my_program():
    with session_scope() as session:
        ThingOne().go(session)
        ThingTwo().go(session)
swimmer
  • 1,971
  • 2
  • 17
  • 28