Après des heures de débogage, et parce que mon organisation n'a pas beaucoup d'expertise Python, je me tourne vers cette communauté pour obtenir de l'aide.Je ne peux pas enregistrer des lignes dans la base de données avec SQLAchemy + Pyramid
Je suis en train de suivre this tutorial dans le but de valider certaines données dans la base de données. Bien qu'aucune erreur ne soit signalée, je n'enregistre aucune ligne. Qu'est-ce que je fais mal?
Lorsque vous essayez de commettre en utilisant le db2Session, je reçois:
transaction doit être commise à l'aide du gestionnaire de transactions.
Mais je ne vois nulle part dans le tutoriel le gestionnaire de transactions utilisé. Je pensais que ce gestionnaire est lié en utilisant zope.sqlalchemy? Pourtant, rien ne se passe autrement. Aider à nouveau serait vraiment apprécié!
je la configuration suivante dans ma fonction principale dans une application Pyramide:
from sqlalchemy import engine_from_config
from .models import db1Session, db2Session
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
db1_engine = engine_from_config(settings, 'db1.')
db2_engine = engine_from_config(settings, 'db2.')
db1Session.configure(bind=db1_engine)
db2Session.configure(bind=db2_engine)
Dans fichiers .models/__ init__py, j'ai:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (scoped_session, sessionmaker)
from zope.sqlalchemy import ZopeTransactionExtension
db1Session = scoped_session(sessionmaker(
extension=ZopeTransactionExtension()))
db2Session =
scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
Dans ./model/db2.py I ont:
class PlateWellResult(Base):
__tablename__ = 'SomeTable'
__table_args__ = {"schema": 'some_schema'}
id = Column("ID", Integer, primary_key=True)
plate_id = Column("PlateID", Integer)
hit_group_id = Column("HitID", Integer, ForeignKey(
'some_schema.HitGroupID.ID'))
well_loc = Column("WellLocation", String)
Les bits pertinents de ma fonction d'économie ressemblent à ceci. ./lib/db2_api.py:
def save_selected_rows(input_data, selected_rows, hit_group_id):
""" Wrapper method for saving selected rows """
# Assume I have all the right data below.
new_hit_row = PlateWellResult(
plate_id=master_plate_id,
hit_group_id=hit_group_id,
well_loc=selected_df_row.masterWellLocation)
db1Session.add(new_hit_row)
# When I try the row below:
# db2Session.commit()
# I get: Transaction must be committed using the transaction manager
# If I cancel the line above, nothing gets committed.
return 'Save successful.'
Cette fonction est appelée de mon spectateur:
@view_config(route_name='some_routename', renderer='json',
permission='create_hit_group')
def save_to_hitgroup(self):
""" Backend to AJAX call to save selected rows to a hit_group """
try:
# Assume that all values were checked and all the right
# parameters are passed
status = save_selected_rows(some_result,
selected_rows_list,
hitgroup_id)
json_resp = json.dumps({'errors': [],
'status': status})
return json_resp
except Exception as e:
json_resp = json.dumps({'errors': ['Error during saving. {'
'0}'.format(e)],
'status': []})
return json_resp
Si vous recherchez la page que vous avez liée pour "transaction", il y a une ligne qui utilise le gestionnaire de transactions: 'avec transaction.manager:'. Personnellement, j'évite de tels globaux alambiqués ou pseudo-globaux. Je suis beaucoup plus heureux de créer ma propre session à chaque requête. – jpmc26
Avez-vous utilisé le paquet de gestion des transactions par requête ['pyramid_tm'] (http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/)? Si non, alors vous ne commettez rien. Vous pouvez également utiliser le gestionnaire de transactions explicitement comme indiqué dans la publication précédente. –
Oh, et si vous l'ajoutez, n'oubliez pas de manuellement 'transaction.doom()' ou 'transaction.abort()' dans votre gestionnaire d'exceptions lorsque vous les attrapez tous. –