: 나는 SQLAlchemy의를 사용하고 적어도 세 기관이있다 engine
, session
그리고 connection
가지고있는, execute
예를 들어 내가 모든 레코드를 선택합니다 그렇다면, 방법을 table
나는이 작업을 수행 할 수 있습니다
engine.execute(select([table])).fetchall()
이
connection.execute(select([table])).fetchall()
심지어 이것
session.execute(select([table])).fetchall()
-결과는 동일합니다.
내가 이해하는 것처럼 누군가 누군가 engine.execute
그것을 사용 하면 create connection
을 열고 session
(Alchemy가 처리합니다) 쿼리를 실행합니다. 그러나 이러한 작업을 수행하는이 세 가지 방법 사이에 전 세계적 차이가 있습니까?
답변
한 줄 개요 :
의 동작은 execute()
모든 경우에 동일하지만, 그들은 3 개 가지 방법에 Engine
, Connection
그리고 Session
클래스.
정확히 무엇입니까 execute()
:
execute()
우리의 행동을 이해하려면 Executable
수업 을 살펴 봐야합니다 . Executable
select (), delete (), update (), insert (), text ()를 포함한 모든 “statement”유형의 객체에 대한 수퍼 클래스입니다. 가능한 가장 간단한 단어로, Executable
SQLAlchemy에서 지원되는 SQL 식 구문입니다.
모든 경우에이 execute()
메소드는 SQL 텍스트 또는 생성 된 SQL 표현식, 즉 SQLAlchemy에서 지원되는 다양한 SQL 표현식 구성 중 하나를 취하여 쿼리 결과를 리턴합니다 ( ResultProxy
a- DB-API
행 오브젝트에 쉽게 액세스 할 수 있도록 커서 오브젝트 랩핑 ).
더 명확하게하기 위해 (개념적 설명만을 위해 권장되는 접근법은 아님) :
Engine.execute()
(연결없는 실행) 외에도 Connection.execute()
, 및 모든 구문 Session.execute()
에서 execute()
직접 사용할 수도 있습니다 Executable
. 이 Executable
클래스에는 자체 구현이 있습니다. execute()
공식 문서에 따라 수행 한 작업에 대한 한 줄 설명 execute()
은 ” 컴파일 및 실행Executable
“입니다. 이 경우 객체 또는 객체 (암시 적으로 객체 를 가져옴 Executable
)와 (SQL 표현식 구성) 을 명시 적으로 바인딩해야 하므로 를 실행할 위치를 알 수 있습니다 .Connection
Engine
Connection
execute()
SQL
다음 예제는이를 잘 보여줍니다. 아래와 같은 테이블이 있습니다.
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
명시 적 실행, 즉 Connection.execute()
-SQL 텍스트 또는 생성 된 SQL 표현식을 다음 execute()
메소드에 전달합니다 Connection
.
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
명시 적 비 연결 실행 ( 즉 Engine.execute()
, SQL 텍스트 또는 생성 된 SQL 표현식 execute()
을 Engine 메소드에 직접 전달) :
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
암시 적 실행 즉 Executable.execute()
, 또한 연결이 없으며 의 execute()
메소드를 호출합니다. 즉 , 표현식 구문 (의 인스턴스 ) 자체 에서 직접 메소드를 Executable
호출 합니다.execute()
SQL
Executable
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
참고 : 설명을 위해 암시 적 실행 예제를 명시했습니다.이 실행 방법은 문서 별로 권장하지 않습니다 .
“암시 적 실행”은 매우 오래된 사용 패턴으로 대부분의 경우 도움보다 혼란스럽고 사용이 권장되지 않습니다. 두 패턴 모두 나중에 응용 프로그램 디자인에서 편리한 “바로 가기”를 과도하게 사용하는 것으로 보이며 나중에 문제가 발생합니다.
당신의 질문:
누군가 engine.execute를 사용하면 연결을 만들고 세션을 열고 (Alchemy가 관심을 갖습니다) 쿼리를 실행합니다.
당신은 “누군가 사용하면 부분 맞아요 engine.execute
이 생성 connection
하지만 대한은”개방 ” session
(연금술 당신을 위해에 대한 염려)하고 실행하는 쿼리를”- 사용 Engine.execute()
하고 Connection.execute()
(거의) 하나 같은 일이 공식에서, Connection
오브젝트가 내재적으로 작성됩니다 나중에는 명시 적으로 인스턴스화합니다. 이 경우 실제로 일어나는 일은 다음과 같습니다.
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
그러나 이러한 작업을 수행하는 세 가지 방법 간에는 전 세계적으로 다른 점이 있습니까?
DB 계층에서 정확히 같은 것입니다. 모두 SQL (텍스트 표현식 또는 다양한 SQL 표현식 구성)을 실행하고 있습니다. 응용 프로그램의 관점에서 두 가지 옵션이 있습니다.
- 직접 실행-
Engine.execute()
또는Connection.execute()
- 사용
sessions
– 효율적 개의 단위 작업으로 트랜잭션을 처리, 쉽게를 통해session.add()
,session.rollback()
,session.commit()
,session.close()
. ORM 즉 매핑 된 테이블의 경우 DB와 상호 작용하는 방법입니다. 단일 요청 중에 이미 액세스했거나 새로 생성 / 추가 된 객체를 즉시 가져올 수 있도록 identity_map 을 제공합니다 .
Session.execute()
궁극적으로 Connection.execute()
SQL 문을 실행하기 위해 명령문 실행 방법을 사용 합니다. Session
응용 프로그램이 데이터베이스와 상호 작용하기 위해 오브젝트를 사용하는 것이 SQLAlchemy ORM의 권장 방법입니다.
문서 에서 발췌 :
SQLAlchemy ORM을 사용할 때 이러한 오브젝트는 일반적으로 액세스되지 않습니다. 대신 Session 개체는 데이터베이스에 대한 인터페이스로 사용됩니다. 그러나 ORM의 상위 레벨 관리 서비스를 사용하지 않고 텍스트 SQL 문 및 / 또는 SQL 표현식 구성을 직접 사용하도록 빌드 된 응용 프로그램의 경우 엔진 및 연결이 왕성한 (그리고 여왕입니까?)입니다.
답변
Nabeel의 답변 은 많은 세부 사항을 다루고 도움이되지만 따르기가 혼란 스럽습니다. 이것이 현재이 문제에 대한 첫 번째 Google 결과이므로이 질문을 발견 한 미래의 사람들을 위해 이해하고 있습니다.
.execute () 실행
OP와 Nabell Ahmed는 plain을 실행할 때 SELECT * FROM tablename
제공된 결과에 차이가 없음을 지적합니다.
이 세 개체 사이의 차이는 그 상황에 따라 중요 해지고 않는 SELECT
문이 또는 더 일반적으로, 당신이 원하는 때와 같은 다른 것들에 사용되는 INSERT
, DELETE
등
엔진, 연결, 세션을 일반적으로 사용하는 경우
-
엔진 은 SQLAlchemy에서 사용하는 가장 낮은 수준의 개체입니다. 그것은 연결 풀 유지 관리 응용 프로그램이 데이터베이스에 이야기해야 할 때마다 사용할 수 있습니다.
.execute()
먼저 호출conn = engine.connect(close_with_result=True)
하고 그 다음에 편리한 방법입니다conn.execute()
. close_with_result 매개 변수는 연결이 자동으로 종료되었음을 의미합니다. (저는 소스 코드를 약간 해석하고 있지만 본질적으로 사실입니다). 편집 : 다음은 engine.execute의 소스 코드입니다.엔진을 사용하여 원시 SQL을 실행할 수 있습니다.
result = engine.execute('SELECT * FROM tablename;') #what engine.execute() is doing under the hood conn = engine.connect(close_with_result=True) result = conn.execute('SELECT * FROM tablename;') #after you iterate over the results, the result and connection get closed for row in result: print(result['columnname'] #or you can explicitly close the result, which also closes the connection result.close()
이것은 기본 사용법 의 문서에서 다룹니다 .
-
연결 은 (위에서 보았 듯이) 실제로 SQL 쿼리를 실행하는 작업입니다. 연결 속성이 닫힐 때 등의 속성에 대한 제어를 강화할 때마다이 작업을 수행해야합니다. 예를 들어, 매우 중요한 예로는 Transaction 을 사용하여 데이터베이스에 변경 사항을 커밋 할시기를 결정할 수 있습니다. 정상적인 사용에서는 변경 사항이 자동 커밋됩니다. 트랜잭션을 사용하면 (예를 들어) 여러 가지 다른 SQL 문을 실행할 수 있으며 그 중 하나에 문제가 있으면 한 번에 모든 변경 내용을 취소 할 수 있습니다.
connection = engine.connect() trans = connection.begin() try: connection.execute("INSERT INTO films VALUES ('Comedy', '82 minutes');") connection.execute("INSERT INTO datalog VALUES ('added a comedy');") trans.commit() except: trans.rollback() raise
이렇게하면 데이터 로그 테이블 생성을 잊어 버린 것처럼 하나의 변경이 실패하면 두 변경 사항을 모두 취소 할 수 있습니다.
따라서 원시 SQL 코드를 실행하고 제어가 필요한 경우 연결을 사용하십시오.
-
세션 은 SQLAlchemy의 ORM (Object Relationship Management) 측면에 사용됩니다 (실제로 가져 오는 방법에서 볼 수 있음
from sqlalchemy.orm import sessionmaker
). 이들은 자동 생성 된 SQL 문을 실행하기 위해 연결 및 트랜잭션을 사용합니다..execute()
세션이 바인딩 된 모든 항목 (일반적으로 엔진이지만 연결될 수 있음)으로 전달되는 편리한 기능입니다.ORM 기능을 사용하는 경우 세션을 사용하십시오. 객체에 바인딩되지 않은 직선 SQL 쿼리 만 수행하는 경우 연결을 직접 사용하는 것이 좋습니다.
답변
다음은 GRANT와 같은 DCL (Data Control Language)을 실행하는 예입니다.
def grantAccess(db, tb, user):
import sqlalchemy as SA
import psycopg2
url = "{d}+{driver}://{u}:{p}@{h}:{port}/{db}".\
format(d="redshift",
driver='psycopg2',
u=username,
p=password,
h=host,
port=port,
db=db)
engine = SA.create_engine(url)
cnn = engine.connect()
trans = cnn.begin()
strSQL = "GRANT SELECT on table " + tb + " to " + user + " ;"
try:
cnn.execute(strSQL)
trans.commit()
except:
trans.rollback()
raise