SQLAlchemy에서 원시 SQL을 어떻게 실행합니까?
플라스크에서 실행되고 SQLAlchemy를 통해 데이터베이스에 인터페이스하는 Python 웹 앱이 있습니다.
원시 SQL을 실행하는 방법이 필요합니다. 쿼리에는 인라인 뷰와 함께 여러 테이블 조인이 포함됩니다.
난 노력 했어:
connection = db.session.connection()
connection.execute( <sql here> )
그러나 게이트웨이 오류가 계속 발생합니다.
답변
시도해 보셨습니까?
result = db.engine.execute("<sql here>")
또는:
from sqlalchemy import text
sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names
답변
SQL Alchemy 세션 개체에는 고유 한 execute
방법이 있습니다.
result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
모든 응용 프로그램 쿼리는 원시 SQL인지 여부에 관계없이 세션 개체를 통과해야합니다. 이를 통해 트랜잭션 이 쿼리를 올바르게 관리 할 수 있으므로 동일한 요청의 여러 쿼리를 단일 단위로 커밋하거나 롤백 할 수 있습니다. 엔진 이나 연결 을 사용하여 트랜잭션 외부로 나가면 미묘한 위험에 노출되어 데이터가 손상 될 수있는 버그를 감지하기 어려울 수 있습니다. 각 요청은 하나의 트랜잭션에만 연결되어야하며이를 사용 db.session
하면 애플리케이션에 해당하는 것입니다.
또한 매개 변수화 된 쿼리를execute
위해 설계되었습니다 . SQL 인젝션 공격으로부터 자신을 보호하기 위해 쿼리에 입력 할 때 예제 와 같이 매개 변수를 사용하십시오 . a 를 두 번째 인수로 전달하여 이러한 매개 변수의 값을 제공 할 수 있습니다 . 여기서 각 키는 조회에 표시되는 매개 변수의 이름입니다. 매개 변수 자체의 정확한 구문은 데이터베이스에 따라 다를 수 있지만 모든 주요 관계형 데이터베이스는이를 특정 형식으로 지원합니다.:val
dict
그것의 가정 SELECT
쿼리,이 반환됩니다 반복 가능 의 RowProxy
객체.
다양한 기술로 개별 열에 액세스 할 수 있습니다.
for r in result:
print(r[0]) # Access by positional index
print(r['my_column']) # Access by column name as a string
r_dict = dict(r.items()) # convert to dict keyed by column names
개인적으로 결과를 namedtuple
s 로 변환하는 것을 선호합니다 .
from collections import namedtuple
Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
print(r.my_column)
print(r)
Flask-SQLAlchemy 확장을 사용하지 않는 경우에도 세션을 쉽게 사용할 수 있습니다.
import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session
engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))
s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
답변
docs : SQL 식 언어 자습서-텍스트 사용
예:
from sqlalchemy.sql import text
connection = engine.connect()
# recommended
cmd = 'select * from Employees where EmployeeGroup = :group'
employeeGroup = 'Staff'
employees = connection.execute(text(cmd), group = employeeGroup)
# or - wee more difficult to interpret the command
employeeGroup = 'Staff'
employees = connection.execute(
text('select * from Employees where EmployeeGroup = :group'),
group = employeeGroup)
# or - notice the requirement to quote 'Staff'
employees = connection.execute(
text("select * from Employees where EmployeeGroup = 'Staff'"))
for employee in employees: logger.debug(employee)
# output
(0, 'Tim', 'Gurra', 'Staff', '991-509-9284')
(1, 'Jim', 'Carey', 'Staff', '832-252-1910')
(2, 'Lee', 'Asher', 'Staff', '897-747-1564')
(3, 'Ben', 'Hayes', 'Staff', '584-255-2631')
답변
from_statement()
및 여기에text()
표시된 것처럼 SELECT SQL 쿼리 결과를 얻을 수 있습니다 . 이 방법으로 튜플을 다룰 필요가 없습니다. 시도 할 수 있는 테이블 이름 을 가진 클래스의 예로 ,User
users
from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
text("SELECT * FROM users where name=:name")).\
params(name='ed').all()
return user
답변
result = db.engine.execute(text("<sql here>"))
실행 <sql here>
하지만 autocommit
모드 에 있지 않으면 커밋하지 않습니다 . 따라서 삽입 및 업데이트는 데이터베이스에 반영되지 않습니다.
변경 후 커밋하려면
result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
답변
Flask Shell에서 SQL 쿼리를 실행하는 방법에 대한 간단한 답변입니다.
먼저 모듈을 매핑하십시오 (모듈 / 앱이 주 폴더에 있고 manage.py이고 UNIX 운영 체제에있는 경우).
export FLASK_APP=manage
플라스크 쉘 실행
flask shell
필요한 것을 가져 오십시오 ::
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
from sqlalchemy import text
쿼리를 실행하십시오.
result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
응용 프로그램이있는 현재 데이터베이스 연결을 사용합니다.