복붙노트

[SQL] 어떻게 플라스크-SQLAlchemy의 응용 프로그램에서 원시 SQL을 실행합니다

SQL

어떻게 플라스크-SQLAlchemy의 응용 프로그램에서 원시 SQL을 실행합니다

당신은 어떻게 SQLAlchemy의 원시 SQL을 실행합니까?

나는 파이썬 웹 응용 프로그램이 그 SQLAlchemy의를 통해 데이터베이스에 플라스크 및 인터페이스에서 실행됩니다.

나는 원시 SQL을 실행할 수있는 방법이 필요합니다. 쿼리는 여러 테이블 인라인 뷰와 함께 조인이 포함됩니다.

난 노력 했어:

connection = db.session.connection()
connection.execute( <sql here> )

하지만 게이트웨이 오류가 점점 계속.

해결법

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

    1.당신이 시도 유무 :

    당신이 시도 유무 :

    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
    
  2. ==============================

    2.SQLAlchemy의 세션 객체는 자신의 실행 방법이있다 :

    SQLAlchemy의 세션 객체는 자신의 실행 방법이있다 :

    result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
    

    그들은 원시 SQL 또는 아닙니다 여부 모든 응용 프로그램 쿼리는 세션 객체를 통과해야한다. 쿼리가 제대로 동일한 요청에 여러 쿼리가 최선을 다하고 있습니다 또는 단일 단위로 다시 롤백 할 수있는 트랜잭션에 의해 관리되는이 보장합니다. 손상된 데이터와 함께 당신을 떠날 수있는 버그를 검출하기 위해서 가능한 하드, 엔진 또는 미묘한의 훨씬 더 큰 위험에 연결 박았을 사용하여 트랜잭션 외출. 각 요청은 하나의 거래와 관련된, 그리고이를 보장 할 db.session를 사용하는 응용 프로그램의 경우입니다해야합니다.

    또한 매개 변수가있는 쿼리를 위해 설계되었습니다 실행을 기록해 둡니다. SQL 주입 공격으로부터 자신을 보호하기 위해 쿼리에 어떤 입력에 대해, 예에서 발 : 같은 매개 변수를 사용합니다. 당신은 쿼리에 표시되는 각 키는 매개 변수의 이름이고 두 번째 인수로 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
    

    개인적으로, 나는 namedtuples로 결과를 변환하는 것을 선호합니다 :

    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)
    

    당신이 플라스크-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})
    
  3. ==============================

    3.문서 : SQL 표현 언어 튜토리얼 - 사용하여 텍스트

    문서 : 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, u'Tim', u'Gurra', u'Staff', u'991-509-9284')
    (1, u'Jim', u'Carey', u'Staff', u'832-252-1910')
    (2, u'Lee', u'Asher', u'Staff', u'897-747-1564')
    (3, u'Ben', u'Hayes', u'Staff', u'584-255-2631')
    
  4. ==============================

    4.당신은 다음과 같이 from_statement () 및 텍스트 ()를 사용하여 SELECT SQL 쿼리의 결과를 얻을 수 있습니다. 당신은 튜플에 이런 식으로 처리 할 필요가 없습니다. 당신이 시도 할 수있는 테이블 이름의 사용자를 갖는 클래스 사용자에 대한 예를 들어,

    당신은 다음과 같이 from_statement () 및 텍스트 ()를 사용하여 SELECT SQL 쿼리의 결과를 얻을 수 있습니다. 당신은 튜플에 이런 식으로 처리 할 필요가 없습니다. 당신이 시도 할 수있는 테이블 이름의 사용자를 갖는 클래스 사용자에 대한 예를 들어,

    from sqlalchemy.sql import text
    .
    .
    .
    user = session.query(User).from_statement(
        text("SELECT * FROM users where name=:name")).\
        params(name='ed').all()
    
    return user
    
  5. ==============================

    5.

    result = db.engine.execute(text("<sql here>"))
    

    실행 하지만 당신은 자동 커밋 모드가 아니라면 그것을 커밋하지 않습니다. 그래서, 삽입 및 업데이트가 데이터베이스에 반영하지 않을 것입니다.

    변경 후 커밋 수행

    result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
    
  6. ==============================

    6.실행 (모듈 / 앱이 주요 폴더에 manage.py 경우 당신은 UNIX 운영 체제에) 먼저, 모듈지도 :

    실행 (모듈 / 앱이 주요 폴더에 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))
    

    이 응용 프로그램을 가지고 현재 데이터베이스 연결을 사용합니다.

  7. ==============================

    7.해당 문서에 설명 된대로 (텍스트 () <바인드 여기 PARAMS>) connection.execute를 사용하여 바인드 매개 변수 봤어? 이 캔 도움이 많은 매개 변수 형식 및 성능 문제를 해결. 아마 게이트웨이 오류는 시간 제한은? 바인딩 매개 변수는 복잡한 쿼리가 실질적으로 더 빨리 실행할 수 있도록하는 경향이있다.

    해당 문서에 설명 된대로 (텍스트 () <바인드 여기 PARAMS>) connection.execute를 사용하여 바인드 매개 변수 봤어? 이 캔 도움이 많은 매개 변수 형식 및 성능 문제를 해결. 아마 게이트웨이 오류는 시간 제한은? 바인딩 매개 변수는 복잡한 쿼리가 실질적으로 더 빨리 실행할 수 있도록하는 경향이있다.

  8. ==============================

    8.당신이 튜플을 피하려면 다른 방법은, 먼저 하나 또는 모든 메소드를 호출하는 것입니다 :

    당신이 튜플을 피하려면 다른 방법은, 먼저 하나 또는 모든 메소드를 호출하는 것입니다 :

    query = db.engine.execute("SELECT * FROM blogs "
                               "WHERE id = 1 ")
    
    assert query.first().name == "Welcome to my blog"
    
  9. from https://stackoverflow.com/questions/17972020/how-to-execute-raw-sql-in-flask-sqlalchemy-app by cc-by-sa and MIT license