Domanda

Sto avendo un problema con SQLAlchemy con PySide (PyQt). Sto cercando di pop-up un QtGui.QDialog, ma quando faccio questo SQLAlchemy genera un'eccezione:

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)

Questo è particolarmente preoccupante perché non ho il codice, da nessuna parte, che anche i tentativi di inserire record in SQL; Sto tentando sempre e solo per interrogare i dati dal database. In realtà, il mio modello DB è di sola lettura rispetto a quanto PySide / PyQt stanno facendo (vale a dire, sto usando un modello di QtGui.QTableView / vista e non v'è alcuna funzione insertRows in quel modello).

Non ho idea di quello che sta succedendo o come risolverlo - ancora una volta, non ho il codice per modificare i record di SQL a tutti, ma ancora i tentativi SQLAlchemy ad essere l'inserimento di record vuoti in una delle mie tabelle SQL. Tutto quello che posso vedere, in fondo, è il modello di dati QTableView sta interrogando il database MOLTO. Sembra proprio che quando ho PopUp questo QDialog (che ha un certo codice in esso per interrogare alcuni colonna della tabella) è gettato questo errore. Stranamente, questo non è coerente, a volte il pop-up appare prima di eccezione, a volte le appare popup dopo l'eccezione. In circostanze normali, il modello di dati QTableView grandi opere, non solo quando ho PopUp questa finestra di dialogo (e ironia della sorte, il popup non utilizza alcun QTableView a tutti, solo i widget standard come QLineEdit, QTextEdit, ecc.)

Se aiuta, sto usando Python 2.7 con SQLAlchemy 0.6.6 (anche con Elixir 0.7.1), e PySide 1.0.0 (e PyQt4 4.8.3). Sono su Windows 7 utilizzando SQL 2008 R2 (Express). E sì, ho provato il riavvio del PC, ma il problema si verifica ancora dopo un riavvio. Sono riluttante a inviare più di codice perché ho un sacco di esso in questo particolare progetto e non riesco a inchiodare il problema specifico nulla.

Sto sperando che qualcuno potrebbe sapere di stranezze in SQLAlchemy e / o PyQt che potrebbero essere collegati a questo. Inoltre sto sperando che posso continuare a utilizzare SQLAlchemy come ho un modello di dati di grandi dimensioni costruito; Sono riluttante, a questo punto, ad abbandonare questo e utilizzare le funzioni SQL di PyQt.

È stato utile?

Soluzione

sono riuscito a rendere questo problema andare via, ma non è ancora molto chiaro per me perché SQLAlchemy stava cercando di inserire righe nel mio database -. Che veramente mi dà fastidio, ma non succede più

In ogni caso, quello che era, credo, accadendo, era legato al mio modello di dati SQLAlchemy e il modo in cui mi è stato accedervi, ecco un frammento di quel modello:

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$'}

Nel mio codice ho bisogno di un modo di ottenere 'belle' nomi delle etichette per una GUI senza dover codificare questo in una GUI (ho cercato di creare un modo dinamico di costruire forme GUI). Così, ho aggiunto il metodo 'prettyname' al mio modello di dati di darmi alcuni specifici metadati dell'applicazione in quel modello di dati. Tutto quello che sto facendo è la restituzione di un dizionario di elementi.

Ho avuto un problema secondario che a volte ho bisogno di ottenere questi dati da l'istanza della classe per gli utenti e, talvolta, per un risultato di query per gli utenti (ad esempio, Users.get_by (id = 1)). Come si è scoperto, il recupero di questi dati doveva essere fatto in due modi. Nelle istanze di classe ho dovuto ottenere il valore in questo modo:

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

Ma quando stavo usando i risultati delle query è stato:

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

SQLAlchemy sembra avere un vero problema quando stavo usando il primo metodo (il metodo di istanza di classe) - in quanto questo è stato utilizzato ogni volta che stavo vedendo l'incidente. Quando stavo usando quest'ultimo caso mi è stato non vedere mai un incidente. Eppure, ho bisogno di accesso a tale metadati nel istanza di classe.

La correzione, o forse dovrei dire quello che si rivelò per risolvere questo problema è venuto da un altro articolo StackOverflow (grazie a tutti StackOverflow - sarei niente senza di te). Ho cambiato la struttura del 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)

Questo mi permette di utilizzare un metodo comune di introspezione per ottenere i dati del dizionario nell'argomento informazioni, a prescindere se sto guardando un'istanza di classe, o un risultato della query. In questo caso io uso il metodo '.table' di una classe o di una query risultato, quindi ottenere la colonna che ho bisogno (.c), quindi utilizzare il metodo .info quella colonna di restituire il dizionario.

In ogni caso, ora SQLAlchemy non cerca più di arbitrariamente Inserisci righe nel database di più.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top