web-dev-qa-db-fra.com

Comment exécuter du SQL brut dans l'application SQLAlchemy-flask

Comment exécutez-vous le SQL brut dans SQLAlchemy?

J'ai une application Web python qui s'exécute sur une fiole et des interfaces avec la base de données via SQLAlchemy. 

J'ai besoin d'un moyen d'exécuter le SQL brut. La requête implique plusieurs jointures de table avec des vues incorporées. 

J'ai essayé:

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

Mais je continue à avoir des erreurs de passerelle.

153
starwing123

As-tu essayé:

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

ou:

from sqlalchemy import text

sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names
229
Miguel

Si vous souhaitez utiliser une session (comme le suggère votre question), utilisez directement sa méthode execute:

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})

Les éléments suivants peuvent être spécifiques à mon pilote de base de données (psycopg2); Je ne suis pas sûr. Peu importe, c'est comme ça que je tire mes valeurs.

from collections import namedtuple

Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
    print(r)

Le point clé est l'appel fetchall(). La partie namedtuple est juste quelque chose que je trouve me facilite la vie en donnant un accès basé sur le nom.

De plus, il s’agit d’une transaction sans / gestion manuelle. Say make_session est une fonction qui crée une session:

>>> s1 = make_session()
>>> s1.execute('CREATE TABLE blah (id INTEGER)')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD86F0>
>>> s1.commit()
>>>
>>> s1.execute('INSERT INTO blah VALUES (1)')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD8870>
>>> s1.execute('SELECT * FROM blah').fetchall()
[(1,)]
>>>
>>> s2 = make_session()
>>> s2.execute('SELECT * FROM blah').fetchall()
[]
>>> s2.close()
>>>
>>> s1.commit()
>>>
>>> s2 = make_session()
>>> s2.execute('SELECT * FROM blah').fetchall()
[(1,)]
>>> s2.close()
>>> s1.close()
113
jpmc26

docs: Tutoriel SQL Expression Language - Utilisation du texte

exemple:

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')
48
Jake Berger

Vous pouvez obtenir les résultats des requêtes SELECT SQL en utilisant from_statement() et text() comme indiqué ici . Vous n'avez pas à traiter avec des tupules de cette façon. Comme exemple pour un utilisateur de classe ayant le nom de table 'utilisateurs', vous pouvez essayer,

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

return user
27
TrigonaMinima
result = db.engine.execute(text("<sql here>"))

exécute le <sql here> mais ne le commet que si vous êtes en mode autocommit. Ainsi, les insertions et les mises à jour ne seraient pas reflétées dans la base de données.

Pour valider après les modifications, faites

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

Ceci est une réponse simplifiée sur la façon d'exécuter une requête SQL à partir de Shell Flask

Commencez par mapper votre module (si votre module/application est manage.py dans le dossier principal et que vous vous trouvez dans un système d'exploitation UNIX), exécutez:

export FLASK_APP=manage

Run Shell Flask

flask Shell

Importer ce dont nous avons besoin ::

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
from sqlalchemy import text

Exécuter votre requête:

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

Ceci utilise la connexion actuelle à la base de données qui contient l'application.

0
Luigi Lopez

Avez-vous essayé d'utiliser connection.execute(text( <sql here> ), <bind params here> ) et de lier les paramètres comme décrit dans la documentation ? Cela peut aider à résoudre de nombreux problèmes de formatage de paramètres et de performances. Peut-être que l'erreur de passerelle est un délai d'attente? Les paramètres de liaison ont tendance à accélérer considérablement l'exécution des requêtes complexes.

0
jhnwsk