engine.execute("SHOW DATABASES;")
이러한 방식으로 mysql에 직접 sql문을 실행시킬 수 있다 (현재 있는 database를 다 보여달라는 명령어다)
어려운 것은 결과값을 받아오는 법이었다.
result= engine.execute("SHOW DATABASES;")
이런 식으로 결과값을 받아올 때, 결과값은 ResultProxy
타입이다. ResultProxy
는 데이터베이스에 대한 포인터 개념일 뿐이다.
for v in result:
print(v)
와 같은 방식으로 프린트는 할 수 있지만
result[0]
처럼 직접 첨자로 사용하려 하면 오류를 뱉는다.
(TypeError: 'ResultProxy' object is not subscriptable)
그렇기때문에 실제로 값을 사용해야 하면 아래와 같은 방법이 필요하다.
result.fetchall()
를 통해 row들을 튜플의 리스트로써 받아올 수 있다.
예를들어 print(result.fetchall())
를 하면
[('fade',), ('information_schema',), ('mysql',), ('performance_schema',), ('sakila',), ('sys',), ('world',)]
이런식으로 튜플의 리스트를 보여준다.
혹은 result.first()
로 하나만 받아올 수도 있다. 물론 튜플의 형태다.
요약
result = engine.execute("SQL문")
을 통해 SQL을 직접 실행 가능- 결과값은
ResultProxy
타입인데 db의 포인터로서 for문을 통해 print는 되지만 직접 얻어올 순 없다.result.fetchall()
,result.first()
등을 통해 튜플의 리스트, 튜플로 결과 칼럼들을 사용할 수 있다.
참고로 튜플은 원래 1개일 경우 끝에 ,가 붙는다. 원래 그렇다.
참고 : 포인터가 넘어가는 방식이라 그런건지, 정확한 이유는 잘 모르겠지만
for문을 통해 한번 순회하면 fetchall()
을 했을 때 텅 비어있다. 한번 순회하면 포인터가 끝에 도달하나보다.
✔ 처음부터 fetchall()
이나 first()
를 사용하는 게 좋겠다.
마찬가지로 fetchall()
같은 것도 다 사용하면 (만약 first()
도 여러번 사용해서 결과 자원을 다 받아오면)
sqlalchemy.exc.ResourceClosedError: This result object is closed.
이런식으로 결과값을 다 받아왔으면 닫히게 된다. 즉슨
result.fetchall()
print(result.fetchall())
이런식으로의 사용은 금물이다. 이미 다 받아와서 아래의 print문때는 받아올 게 없다고 오류가 뜬다. (ResourceClosedError)
row = result.fetchall()
print(row)
이렇게 한 번만 받아놓고 받아놓은 변수를 사용하자
https://stackoverrun.com/ko/q/10392087