programing

sqalchemy 세션에서 개체 새로 고침 정보

css3 2023. 9. 17. 13:27

sqalchemy 세션에서 개체 새로 고침 정보

나는 sqalchemy와 객체들에 대한 의심을 다루고 있습니다!

두 세션이 있는 상황인데 두 세션 모두 동일한 객체가 조회되었습니다!어떤 특정한 일 때문에 세션 중 하나를 닫을 수 없습니다.객체를 수정하고 A세션에서 변경을 커밋했는데 B세션에서는 수정 없이 속성이 초기 속성입니다!

변경 사항을 전달하기 위해 알림 시스템을 구현해야 합니까 아니면 sqalchemy에 내장된 방법이 있습니까?

세션은 이와 같이 작동하도록 설계되었습니다.세션 B에 있는 개체의 속성은 세션 B에서 처음 쿼리했을 때의 개체 속성을 유지합니다.또한 SQLLchemy는 다른 세션의 개체가 변경될 때 자동으로 새로 고침을 시도하지 않을 것이며, 이와 같은 것을 생성하는 것이 현명하다고 생각하지 않습니다.

각 세션의 수명은 데이터베이스에서 하나의 트랜잭션으로 적극적으로 생각해야 합니다.세션에서 개체가 오래된 문제를 처리해야 하는 방법과 시기는 SQLLechemy에 내장된 알고리즘(또는 SQLLechemy의 확장 기능)으로 해결할 수 있는 기술적 문제가 아닙니다. 솔루션을 직접 결정하고 코딩해야 하는 "비즈니스" 문제입니다."올바른" 응답은 이것이 문제가 아니라는 것을 말하는 것일 수도 있습니다. 세션 B에서 발생하는 논리는 세션 B가 시작될 때의 데이터를 사용하는 경우 유효할 수 있습니다.당신의 "문제"는 실제로 문제가 되지 않을 수도 있습니다.실제로 문서에는 세션 사용 시기에 대한 전체 섹션이 있지만, 모든 것을 완벽하게 해결할 수 있는 솔루션을 원한다면 매우 냉담한 반응을 얻을 수 있습니다.

세션은 일반적으로 데이터베이스 액세스가 예상되는 논리 연산의 시작 부분에서 구성됩니다.

세션은 데이터베이스와 대화하는 데 사용될 때마다 통신을 시작하는 즉시 데이터베이스 트랜잭션을 시작합니다.자동 커밋 플래그가 권장 기본값인 False로 남아 있다고 가정하면 세션이 롤백, 커밋 또는 닫힐 때까지 이 트랜잭션은 계속 진행 중입니다.세션은 이전 트랜잭션 종료 후에 다시 사용될 경우 새 트랜잭션을 시작합니다. 이를 통해 세션은 한 번에 하나씩만 처리되지만 많은 트랜잭션에서 수명을 가질 수 있습니다.우리는 이 두 가지 개념을 거래 범위와 세션 범위라고 부릅니다.

여기서 의미하는 바는 SQLAlchemy ORM이 개발자가 자신의 응용 프로그램에서 이 두 가지 범위를 설정하도록 장려한다는 것입니다. 범위가 시작되고 끝날 때뿐만 아니라 이러한 범위의 확장도 마찬가지입니다. 예를 들어 단일 세션 인스턴스가 함수 또는 메서드 내의 실행 흐름에 로컬인 경우, 글로벌 o입니다.전체 응용 프로그램 또는 이 둘 사이의 어딘가에서 사용되는 bject.

개발자가 이 범위를 결정해야 하는 부담은 SQLAlchemy ORM이 데이터베이스를 어떻게 사용해야 하는지에 대해 강력한 의견을 가지고 있는 분야 중 하나입니다.작업 패턴의 단위는 구체적으로 시간이 지남에 따라 변화를 누적하고 주기적으로 플러시하여 인메모리 상태를 로컬 트랜잭션에 존재하는 것으로 알려진 것과 일치시키는 것 중 하나입니다.이 패턴은 의미 있는 트랜잭션 범위가 있을 때만 유효합니다.

그렇기는 하지만, 상황의 운영 방식을 바꾸기 위해 할 수 있는 몇 가지 방법이 있습니다.

첫째, 세션이 열려 있는 시간을 줄일 수 있습니다.세션 B가 개체를 쿼리하고 있으면 나중에 해당 개체(동일한 세션에서)를 사용하여 속성을 최신 상태로 유지하려는 작업을 수행하게 됩니다.한 가지 해결책은 이 두 번째 작업을 별도의 세션에서 수행하도록 하는 것입니다.

다른 방법은 문서에 나와 있듯이 만료/새로 고침 방법을 사용하는 것입니다.

# immediately re-load attributes on obj1, obj2
session.refresh(obj1)
session.refresh(obj2)

# expire objects obj1, obj2, attributes will be reloaded
# on the next access:
session.expire(obj1)
session.expire(obj2)

을 사용할 수 .session.refresh()세션이 이미 이전에 개체를 쿼리한 경우에도 개체의 최신 버전을 즉시 가져옵니다.

세션이 선택한 데이터베이스에서 최신 값을 업데이트하도록 하려면 다음을 실행합니다.

session.expire_all()

기본 동작 및 세션 수명에 대한 우수한 DOC

방금 이 문제가 있었는데 어떤 이유에서인지 기존 솔루션이 제게 맞지 않았습니다.무슨 일이 있었는지는session.commit()된 값을 . 호출 후 데이터베이스에서 업데이트된 값이 개체에 전달되었습니다.

TL;DR 세션 동기화 작업을 수행하는 대신, (여러) 세션을 사용하지 않고 엔진에서 직접 SQLChemy Core 구문으로 작업을 합리적으로 쉽게 코딩할 수 있는지 확인합니다.

SQL 및 JDBC 경험이 있는 사람의 경우, SQLAlchemy에 대해 알아야 할 중요한 한 가지 사항이 있습니다. 안타깝게도 여러 문서를 몇 달 동안 명확히 읽지 못했습니다. SQLAlchemy는 Core와 ORM이라는 두 가지 근본적으로 다른 부분으로 구성되어 있습니다.ORM 문서는 웹사이트에 먼저 나열되어 있고 대부분의 예에서 ORM과 유사한 구문을 사용하기 때문에 SQL/JDBC 측면에서 ORM에 대해 생각할 때 오류와 혼란에 대해 스스로 설정할 수 있습니다.ORM은 실제 SQL 문이 실행되는 방법과 시기를 완벽하게 제어하는 자체 추상화 계층을 사용합니다.경험칙에 따르면 세션은 생성 및 삭제 비용이 저렴하며, 프로그램의 흐름과 논리에서 재쿼리, 동기화 또는 다중 쓰레드를 야기할 수 있는 어떤 것에도 다시 사용해서는 안 됩니다.반면 코어는 JDBC Driver와 매우 유사한 직접 노스릴 SQL입니다.문서에서 Core over ORM을 사용하여 "권장"하는 한 곳이 있습니다.

카운터를 늘리거나 로그 테이블 내에 추가 행을 삽입하는 등의 간단한 SQL 작업이 바로 Connection에서 수행되는 것이 좋습니다.Connection을 처리할 때는 SQL Expression Language Tutorial에 설명된 작업과 같이 코어 수준의 SQL 작업이 사용될 것으로 예상됩니다.

연결을 사용하면 DB의 레코드 내용이 변경된 경우에도 특정 레코드의 Session: requery를 사용하는 것과 동일한 부작용이 발생하는 것으로 보입니다.따라서 Connections는 DB 컨텐츠를 "실시간"으로 읽기 위해 세션만큼 "신뢰할 수 없는" 상태이지만, 엔진을 직접 실행하면 풀에서 Connection 개체를 선택할 때(검색한 Connection이 특정 열린 Connection과 비교적 쿼리와 동일한 "재사용" 상태가 되지 않을 경우) 정상적으로 작동하는 것으로 보입니다.SA 문서에 따라 Result 개체를 명시적으로 닫아야 합니다.

격리 수준은 어떻게 설정됩니까?

SHOW GLOBAL VARIABLES LIKE 'transaction_isolation';

기본적으로 mysql innodbtransaction_isolation로 설정됩니다.REPEATABLE-READ.

+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+

다음으로 설정하는 것을 고려합니다.READ-COMMITTED.

sqalchemy 엔진에 대해서는 다음을 통해서만 설정할 수 있습니다.

create_engine("mysql://<connection_string>", isolation_level="READ COMMITTED")

다른 선택지는 다음과 같습니다.

engine = create_engine("mysql://<connection_string>")
engine.execution_options(isolation_level="READ COMMITTED")

또는 다음을 통해 DB에 전역적으로 설정합니다.

SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

그리고.

https://docs.sqlalchemy.org/en/14/orm/session_transaction.html#setting-transaction-isolation-levels-dbapi-autocommit

만약 당신이 잘못된 모델을 에 추가했다면.session, 할 수 있는 작업:

db.session.rollback()

비동기에 대해서도 비슷한 문제가 있었습니다.비동기 IO 사용의 경우await engine.dispose() 수술후에

언급URL : https://stackoverflow.com/questions/19143345/about-refreshing-objects-in-sqlalchemy-session