복붙노트

[SQL] 역할을 설정할 때 SQLAlchemy의 변경 내용을 커밋하지

SQL

역할을 설정할 때 SQLAlchemy의 변경 내용을 커밋하지

나는 SQLAlchemy의 엔진을 사용하여 테이블을 만드는거야,하지만 내 생성 문이 오류없이 실행해도 나는 사전에 역할을 설정하려고하면, 테이블이 데이터베이스에 표시되지 않습니다.

url = 'postgresql://{}:{}@{}:{}/{}'
url = url.format(user, password, host, port, db)

engine = sqlalchemy.create_engine(url)

# works fine
engine.execute("CREATE TABLE testpublic (id int, val text); \n\nINSERT INTO testpublic VALUES (1,'foo'), (2,'bar'), (3,'baz');")
r = engine.execute("select * from testpublic")
r.fetchall() # returns expected tuples
engine.execute("DROP TABLE testpublic;")

# appears to succeed/does NOT throw any error
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text);")

# throws error "relation testpublic does not exist"
engine.execute("select * FROM testpublic")

문맥, 나는 파이썬 3.6, SQLAlchemy의 버전 1.2.17과 포스트 그레스 11.1 및 역할 "READ_WRITE"절대적 존재 (I는 pgadmin에서 위의 정확한 순서를 실행 아무 문제가) 공공 장소에서 테이블을 만드는 데 필요한 모든 권한을 가지고에입니다.

이 경우 어떻게 해결하는 이유는 사람의 노하우합니까?

해결법

  1. ==============================

    1.SQLAlchemy의는 각 문 다음에 커밋 발행하기로 결정 방법은 다음과 같습니다 문제.

    SQLAlchemy의는 각 문 다음에 커밋 발행하기로 결정 방법은 다음과 같습니다 문제.

    텍스트가 engine.execute에 전달되는 경우, SQLAlchemy의 텍스트가 다음과 같은 정규 표현식을 사용하여 DML이나 DDL인지 확인하려고합니다. 여기 소스에서 찾을 수 있습니다

    AUTOCOMMIT_REGEXP = re.compile(
        r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
    )
    

    그들은 선행 공백을 무시하고 텍스트의 시작에있어 경우에만 단어를 검색합니다. 첫 번째 시도 # 잘 작동하는 동안 그래서, 두 번째 예는 첫 번째 단어는 SET이기 때문에 명령문이 실행 된 후 발행 할 필요가있는 커밋 인식하지 못합니다.

    그것은 # 나타납니다 성공하기 때문에 대신 SQLAlchemy의 문제는 롤백 / 오류가 발생하지 않습니다.

    가장 간단한 해결책은 수동으로 커밋하는 것입니다.

    예:

    engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
    

    문서에서와 같이 나, 텍스트와 세트 자동 커밋 = TRUE에서 SQL을 포장

    stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
    e.execute(stmt)
    
  2. from https://stackoverflow.com/questions/56156329/sqlalchemy-not-committing-changes-when-setting-role by cc-by-sa and MIT license