Question

Je vais avoir un problème à l'aide SQLAlchemy avec PySide (PyQt). Je suis en train de pop-up un QtGui.QDialog, mais quand je le fais SQLAlchemy lève une exception:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\preo\preodb\dbviewandmodel.py", line 32, in rowCount
    return len(self.rows())    
  File "C:\Python27\lib\site-packages\preo\preodb\dbviewandmodel.py", line 30, in rows
    return self.tableobj.query.all()
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\query.py", line 1579, in all
return list(self)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\query.py", line 1688, in __iter__
    self.session._autoflush()
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\session.py", line 862, in _autoflush
    self.flush()
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\session.py", line 1388, in flush
    self._flush(objects)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\session.py", line 1469, in _flush
    flush_context.execute()
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\unitofwork.py", line 302, in execute
    rec.execute(self)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\unitofwork.py", line 446, in execute
    uow
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\orm\mapper.py", line 1878, in _save_obj
    execute(statement, params)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\base.py", line 1191, in execute
    params)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\base.py", line 1271, in _execute_clauseelement
    return self.__execute_context(context)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\base.py", line 1302, in __execute_context
    context.parameters[0], context=context)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\base.py", line 1401, in _cursor_execute
    context)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\base.py", line 1394, in _cursor_execute
    context)
  File "C:\Python27\lib\site-packages\sqlalchemy-0.6.6-py2.7.egg\sqlalchemy\engine\default.py", line 299, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (IntegrityError) ('23000', "[23000] [Microsoft][ODBC
SQL Server Driver][SQL Server]Violation of UNIQUE KEY
constraint 'UQ__users__F3DBC5720DAF0CB0'. Cannot insert duplicate key in
object 'dbo.users'. (2627) (SQLExecDirectW); [01000] [Microsoft][ODBC SQL Server
Driver][SQL Server]The statement has been terminated. (3621)") u'INSERT INTO users
(username, fullname, email, passwordmd5) OUTPUT inserted.id VALUES (?, ?, ?, ?)'
(None, None, None, None)

Cela est particulièrement troublant parce que je n'ai pas de code, nulle part, que même les tentatives d'insérer des enregistrements dans SQL; Je ne fais que jamais tente d'interroger les données de la base de données. En fait, mon modèle DB est en lecture seule par rapport à ce que PySide / PyQt font (à savoir, j'utilise un modèle QtGui.QTableView / vue et il n'y a pas de fonction insertRows dans ce modèle).

je ne sais pas ce qui se passe ou comment le résoudre - encore une fois, je ne code pour modifier des enregistrements SQL du tout, mais les tentatives sqlalchemy pour être insérer des enregistrements vides dans l'une de mes tables SQL. Tout ce que je peux voir, en arrière-plan, est le modèle de données QTableView est la base de données interroge beaucoup. Il semble juste que quand je Popup ce QDialog (qui a un certain code pour interroger une colonne de table) cette erreur est levée. Bizarrement, ce ne correspond pas, quelque temps la fenêtre contextuelle apparaît d'abord avant que l'exception, parfois la fenêtre contextuelle apparaît après l'exception. Dans des circonstances normales, le modèle de données QTableView fonctionne très bien, mais pas quand je Popup cette boîte de dialogue (et ironiquement, la fenêtre n'utilise pas QTableView du tout, à des widgets standards comme QLineEdit, QTextEdit, etc.)

Si elle aide, j'utilise Python 2.7 avec SQLAlchemy 0.6.6 (également avec Elixir 0.7.1), et PySide 1.0.0 (et PyQt4 4.8.3). Je suis sous Windows 7 en utilisant SQL Server 2008 R2 (Express). Et oui, je l'ai essayé de redémarrer le PC, mais le problème persiste après un redémarrage. Je suis réticent à poster plus de code parce que j'ai beaucoup dans ce projet et je ne peux pas clouer le spécifique tout problème.

J'espère que quelqu'un pourrait connaître des bizarreries dans SQLAlchemy et / ou PyQt qui pourraient être liés à cela. Je suis aussi en espérant que je peux continuer à utiliser SQLAlchemy comme je l'ai un grand modèle de données intégré; Je suis réticent, à ce stade, d'abandonner cela et utiliser les fonctions SQL PyQt.

Était-ce utile?

La solution

J'ai réussi à faire de ce problème disparaîtra, mais il est toujours pas vraiment clair pour moi pourquoi SQLAlchemy a essayé d'insérer des lignes dans ma base de données -. Qui me dérange vraiment, mais il ne se passe plus

En tout cas, ce qui était, je pense, en passant, était liée à mon modèle de données SQLAlchemy et la façon dont j'accéder, voici un extrait de ce modèle:

from elixir import *

metadata.bind = 'mssql+pyodbc://username:password/dbname'
metadata.bind.echo = False

class Users(Entity):
    using_options(tablename = 'users')
    username = Field(String(50), unique=True)
    fullname = Field(String(255))
    email = Field(String(255))
    passwordmd5 = Field(String(32))
    def __repr__(self):
        return "<Users ({})({})({})>".format(self.username, self.fullname, self.email)
    def prettyname(self):
        return {'username':'User Name', 'fullname':'Full Name', 'email':'Email Address', 'passwordmd5':'$hidden$'}

Dans mon code, je besoin d'un moyen d'obtenir « jolis » noms d'étiquettes pour une interface graphique sans avoir à coder en dur cela dans une interface graphique (je l'ai essayé de créer un moyen dynamique de la construction des formes GUI). Donc, j'ai ajouté la méthode « prettyname » à mon modèle de données pour me donner des métadonnées spécifiques d'application dans ce modèle de données. Tout ce que je fais est de retour un dictionnaire d'éléments.

J'ai eu un problème secondaire que parfois je avais besoin pour obtenir ces données de l'instance de classe pour les utilisateurs et parfois pour un résultat de requête pour les utilisateurs (par exemple, Users.get_by (id = 1)). En fin de compte, la récupération de ces données devait être fait de deux façons. Dans les instances de classe que je devais obtenir la valeur de cette façon:

prettyname = Users().prettyname()['username']

Mais quand j'utilisais les résultats de la requête était:

prettyname = queryresult.prettyname()['username']

SQLAlchemy semble avoir un vrai problème quand j'utilisais l'ancienne méthode (la méthode d'instance de classe) - comme cela a été utilisé chaque fois que je voyais l'accident. Quand j'utilisais ce dernier cas que je ne voyais un accident. Pourtant, il me fallait l'accès à ces métadonnées dans l'instance de classe.

Le correctif, ou devrais-je dire ce qui se révéla pour résoudre ce problème est venu d'un autre article Stackoverflow (merci à tout le monde Stackoverflow - je serais rien sans toi). J'ai changé la structure du dbmodel:

class Users(Entity):
    using_options(tablename = 'users')
    username = Field(String(50), unique=True, info={'prettyname':'User Name'})
    fullname = Field(String(255), info={'prettyname':'Full Name'})
    email = Field(String(255), info={'prettyname':'Email Address'})
    passwordmd5 = Field(String(32), info={'hidden':True})
    def __repr__(self):
        return "<Users ({})({})({})>".format(self.username, self.fullname, self.email)

Cela me permet d'utiliser une méthode commune d'introspection pour obtenir les données du dictionnaire dans l'argument info, peu importe si je regarde une instance de classe, ou un résultat de la requête. Dans ce cas, j'utilise la méthode « .table » soit la classe ou des résultats des requêtes, puis obtenir la colonne que j'ai besoin (.c), utiliser la méthode de cette .info colonne pour retourner le dictionnaire.

Quel que soit le cas, maintenant sqlalchemy ne cherche plus à insérer arbitrairement des lignes dans la base de données plus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top