2011-03-16 41 views
0

我在使用的SQLAlchemy與PySide(PyQt的)問題。我試圖彈出一個QtGui.QDialog,但是當我這樣做的SQLAlchemy拋出異常:SQLAlchemy的IntegrityError

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) 

這是特別麻煩,因爲我沒有代碼,任何地方,甚至試圖將記錄插入到SQL;我只是試圖從數據庫中查詢數據。事實上,我的數據庫模型是隻讀的就什麼PySide/PyQt的正在做的(即,我使用QtGui.QTableView模型/視圖並且在該模型沒有insertRows功能)。

我不知道發生什麼事或如何解決它 - 再一次,我沒有代碼來修改SQL記錄,但仍然SQLAlchemy試圖插入空白記錄到我的SQL表之一。我只能在後臺看到QTableView數據模型正在查詢數據庫A LOT。這似乎只是當我跳出這個QDialog(裏面確實有一些代碼在它來查詢一些表列)引發此錯誤。奇怪的是,這是不一致的,有時候彈出窗口會先出現在異常之前,有時彈出窗口會出現在異常之後。在正常情況下,該QTableView數據模型的偉大工程,只是沒有當我彈出此對話框(諷刺的是,彈出沒有使用任何QTableView可言,只是標準的小部件一樣QLineEdit的,的QTextEdit等)

如果幫助,我使用Python 2.7使用SQLAlchemy的0.6.6(也與靈藥0.7.1),和PySide 1.0.0(和PyQt4的4.8.3)。我在使用SQL 2008 R2(Express)的Windows 7上。是的,我試過重新啓動電腦,但重新啓動後問題仍然存在。我不願意發佈更多的代碼,因爲我在這個特定的項目中有很多這樣的代碼,並且我無法確定具體的問題。

我希望有人會知道SQLAlchemy的和/或PyQt的怪事,可能與此有關的。我也希望我可以繼續使用SQLAlchemy,因爲我建立了一個大型數據模型;在這一點上,我不情願放棄這個並使用PyQt的SQL特性。

+1

select語句可能沒有做任何事情,但在查詢之前可能會發生某些情況。當查詢運行時,它將刷新仍然要做的任何更改(例如插入用戶)。我們能否看到「dbviewandmodel.py」文件的其餘部分? – 2011-03-17 00:44:12

+0

當發生這種情況時,我仍然沒有做任何類型的數據庫修改(沒有插入,沒有對該數據庫中的任何數據進行編輯),只是查詢數據。我想我已經找到了一種不讓這種崩潰發生的方式(不是真正的修復,更像是,我可以通過不做某些特定的事情來實現它)。我會添加一個答案,因爲它有點冗長。 – Raceyman 2011-03-17 15:03:17

回答

0

我已經設法讓這個問題消失了,但它仍然不是很清楚爲什麼SQLAlchemy試圖在我的數據庫中插入行 - 這真的困擾我,但它不再發生。

無論如何,究竟是什麼,我想,發生的事情,是關係到我SQLAlchemy的數據模型,我正在訪問的方式,這裏就是模型的一個片段:

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

在我的代碼需要一種爲GUI獲取「漂亮」標籤名稱的方法,而不必在GUI中對此進行硬編碼(我一直在試圖創建一種構建GUI表單的動態方法)。因此,我在我的數據模型中添加了'prettyname'方法,以便在該數據模型中爲我提供一些特定於應用程序的元數據。我所做的只是返回一個項目的字典。

我在一個次要問題有時我需要得到來自類別實例這個數據爲用戶和有時用於用戶的查詢結果(例如,Users.get_by(ID = 1))。事實證明,檢索這些數據必須以兩種方式完成。在類的實例,我不得不獲取的價值是這樣的:

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

但是,當我使用的查詢結果是:

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

SQLAlchemy的好像有,當我用的是前者的一個現實問題方法(類實例方法) - 因爲每當我看到崩潰時就會使用它。當我使用後一個例子時,我從未看到崩潰。不過,我需要訪問類實例中的元數據。

該修復程序,或者我應該說什麼原來解決這個問題來自另一個Stackoverflow文章(謝謝大家在Stackoverflow - 我沒有你什麼都沒有)。我改變了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) 

這允許我使用內省的常用方法獲得的信息參數字典數據,不管我在看一個類的實例,或者查詢結果。在這種情況下,我使用類或查詢結果的'.table'方法,然後獲取我需要的列(.c),然後使用該列的.info方法返回字典。

無論如何,現在SQLAlchemy不再試圖在數據庫中隨意插入行。

+0

由於您從未發佈導致問題的確切代碼,因此我無法確定。但是,您上面的代碼片段中顯示了'prettyname = Users()。prettyname()['username']'。由於您使用Elixer,因此此行可能會導致寫入用戶表。 'Users()'將創建一個新的Users實例。 Elixer會將此添加到會話中。此調用後完成的查詢將嘗試提交新的Users實例。因此,如果此代碼段位於您的代碼中,則插入到用戶表中將是正確的行爲。 – 2011-03-17 17:12:24

+0

這很有道理,尤其是考慮到我無法確定問題出現在代碼的哪裏。該代碼行儘可能接近問題出現的地方。我會盡量避免以這種方式繼續使用Users()構造。謝謝! – Raceyman 2011-03-17 18:57:58