我有一个名为
appendTable()
的方法,它基本上采用表的名称和 columns=data
作为关键字参数。我采用关键字参数并使用它来构建一个 DataFrame
对象,然后我使用 dataframe.to_sql()
方法将该行附加到我的数据库表中。此处显示:
def appendTable(self, tableName, **kwargs):
dataFrame = pd.DataFrame(data=[kwargs])
print(dataFrame)
with self.connection_handling():
with threadLock:
dataFrame.to_sql(tableName, con=self.connection.dbEngine, schema="dbo", index=False, if_exists='append')
例如我会像这样使用这个方法:
self.appendTable(tableName="Notebook", FormID=ID, CompressedNotes=notebook)
我的表设计是在 Microsoft SQL Server 中,看起来像这样:
NotebookID | int | primary auto-incrementing key
FormID | int | foreign key to a form table
Notes | varchar(MAX) | allow-nulls : True
CompressedNotes | varbinary(MAX) | allow-nulls : True
我传递的数据来自 PyQt5 TextEdit(用作笔记本),它给我文本/图像作为 HTML 代码,然后我编码数据并使用此处显示的
zlib.compress()
压缩它:
notebook_html = self.noteBookTextEdit.toHtml()
notebookData = zlib.compress(notebook_html.encode())
我打印数据类型和数据帧,发现它一直是预期的数据类型。我还添加到我已经使用多年的数据库表/服务器。
Notebook data type: <class 'bytes'>
FormID CompressedNotes
0 163 b'x\x9c\x03\x00\x00\x00\x00\x01'
生成的 SQL 如下所示:
SQL: INSERT INTO dbo.[Notebook] ([FormID], [CompressedNotes]) VALUES (?, ?)
parameters: ('163', b'x\x9c\x03\x00\x00\x00\x00\x01')
最近,当我为一个
VARBINARY(MAX)
的列传递二进制信息时,我出现了这个错误:
Could not execute cursor!
Reason: (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Implicit conversion from data type varchar(max) to varbinary(max) is not allowed. Use the CONVERT function to run this query. (257) (SQLExecDirectW);
[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Statement(s) could not be prepared. (8180)')
[SQL: INSERT INTO dbo.[Notebook] ([FormID], [CompressedNotes]) VALUES (?, ?)]
[parameters: ('163', b'x\x9c\x03\x00\x00\x00\x00\x01')]
(Background on this error at: https://sqlalche.me/e/20/f405)
自从这个问题开始以来我所做的唯一不同是我通过
appendTable()
运行 QThread()
方法而不是使用 threading.Thread()
因为我想访问一些 signals
和 slots
。但我仍然使用线程锁来确保多个线程不会同时尝试使用我的数据库引擎。而且我已经这样做了很长时间,但我不确定线程锁是否适用于 QThreads(我认为它适用)。