내가 아는 한 ORM이 대량 삽입을 발행하는 방법은 없습니다. 근본적인 이유는 SQLAlchemy가 각 개체의 ID (즉, 새 기본 키)를 추적해야하고 대량 삽입이이를 방해하기 때문이라고 생각합니다. 예를 들어 foo
테이블에 id
열이 있고 Foo
클래스에 매핑 되어 있다고 가정합니다 .
x = Foo(bar=1)
print x.id
# None
session.add(x)
session.flush()
# BEGIN
# INSERT INTO foo (bar) VALUES(1)
# COMMIT
print x.id
# 1
SQLAlchemy는 x.id
다른 쿼리를 실행하지 않고 값을 선택 했으므로 INSERT
명령문 에서 직접 값을 얻었음을 추론 할 수 있습니다 . 동일한 인스턴스 를 통해 생성 된 객체에 대한 후속 액세스가 필요하지 않은 경우 삽입을 위해 ORM 레이어를 건너 뛸 수 있습니다.
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy는 이러한 새 행을 기존 개체와 일치시킬 수 없으므로 후속 작업에 대해 새로 쿼리해야합니다.
오래된 데이터에 관한 한, 세션에는 데이터베이스가 세션 외부에서 변경되는시기를 알 수있는 기본 제공 방법이 없다는 점을 기억하는 것이 좋습니다. 기존 인스턴스를 통해 외부에서 수정 된 데이터에 액세스하려면 인스턴스가 만료 됨으로 표시되어야합니다 . 이것은 기본적으로 발생 session.commit()
하지만, 호출하여 수동으로 수행 할 수 있습니다 session.expire_all()
또는 session.expire(instance)
. 예 (SQL 생략) :
x = Foo(bar=1)
session.add(x)
session.commit()
print x.bar
# 1
foo.update().execute(bar=42)
print x.bar
# 1
session.expire(x)
print x.bar
# 42
session.commit()
expires x
이므로 첫 번째 print 문은 암시 적으로 새 트랜잭션을 열고 x
의 속성을 다시 쿼리 합니다. 첫 번째 print 문을 주석 처리하면 새 쿼리가 업데이트 이후까지 생성되지 않기 때문에 두 번째 문이 올바른 값을 선택한다는 것을 알 수 있습니다.
이것은 트랜잭션 격리의 관점에서 의미가 있습니다. 트랜잭션 사이의 외부 수정 만 선택해야합니다. 이로 인해 문제가 발생하는 경우 즉시 .NET Framework에 도달하는 대신 애플리케이션의 트랜잭션 경계를 명확히하거나 다시 생각하는 것이 좋습니다 session.expire_all()
.