python - Python:读取 Access 数据库
问题描述
直到今天,这个 Python 脚本一直运行良好。FROM
我最近在子句中列出的表中添加了一列。但是,它不是错误消息中列出的字段。
我也尝试添加pyodbc.pooling = False
到代码中,但没有任何改变。
我很茫然,任何帮助将不胜感激。
# Load the needed packages
import pyodbc
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
# Define the connection parameters for MS Access
myDataSources = pyodbc.dataSources()
access_driver = myDataSources['MS Access Database']
file = '\Datasets\BookData.accdb'
# Connect to MS Access
cnxn = pyodbc.connect(Driver = access_driver, DBQ = file)
# Create a query which pulls in the correct data from MS Access
query = pd.read_sql_query('''SELECT * FROM table''', cnxn)
# Close the connection to the MS Access database
cnxn.close()
错误信息
DatabaseError: Execution failed on sql 'SELECT * FROM table': ('HY000', "[HY000] [Microsoft][ODBC Microsoft Access Driver] 指定的字段 'different_table.[field] 可以引用多个表SQL 语句的 FROM 子句。(-3007) (SQLExecDirectW)")
解决方案
如前所述,SQL 查询中的可能表不是实际表,而是存储的查询或视图(如在其他数据库中使用的),它可以像表一样查询。Access 引发错误,因为在查询中的某处您引用了没有别名表的重复字段。例如,Customers和Orders表可以有一个名为CustomerID的字段,您可以运行以下表单:
SELECT CustomerID, ...
FROM Customers c
INNER JOIN Orders o
ON c.CustomerID = o.CustomerID
甚至运行这个查询:
SELECT *
FROM Customers c
INNER JOIN Orders o
ON c.CustomerID = o.CustomerID
然后在 Python 中,您调用此表单,由于CustomerID的多个来源而引发错误:
SELECT * FROM myStoredQuery
为什么这个错误现在出现而不是以前出现?因为您可能在基础表中添加了相同的命名列,然后*
在SELECT
顶部查询的子句中使用。因此,添加到任何引用表的任何新列都会被拉入最终查询。
要解决此问题,请考虑为任何潜在的名称冲突设置别名。正如大多数运行 SQL(Python 之外)的应用程序所建议的那样:
始终明确标识子句中的列,
SELECT
并且不要缩写*
.c.CustomerID
当查询(即,或)中引用了多个表(o.CustomerID
例如使用连接)时,始终用句号限定列的表源。
查看调整后的 SQL:
SELECT c.CustomerID AS Customer_CustomerID,
o.CustomerID AS Order_CustomerID,
...
FROM Customers c
INNER JOIN Orders o
ON c.CustomerID = o.CustomerID
虽然写出每一列似乎很乏味,但这样做有助于可维护性,因为您可以控制并清楚地看到预期的输出,并考虑新的、删除的、重复的或特殊命名的列等重组更改。也许您也不需要 Pandas 中的所有列,因此可以在SELECT
.
最后,请记住 SQL 是一种声明性的专用语言,旨在以用户可读的形式向数据库引擎发送显式命令。引擎使用不同的代码来处理请求。对于作为 Window .dll 的 Access 的 Jet/ACE 引擎,这可能是 C 或 C++。
推荐阅读
- regex - 如何使用可选的无序查询字符串重定向 URL 并将其保存在 Nginx 中
- vue.js - 动作中的 Vuex 访问状态很奇怪
- python - 每次更新我的条目时如何调用函数
- javascript - 在 flatpickr 中允许日期小于 minDate
- reactjs - 从 mapstatetoprops 重构为 React 中的钩子
- capacitor - 在离子电容器 LocalNotification 中每天但在不同时间重复相同通知的最佳方式
- node.js - 构建 docker 映像时,npm install 在 skaffold 中失败
- javascript - Discord Bot 用于踢出代码中由 id 确定的特定用户
- amazon-dynamodb - DynamoDB Streams - 多个子分片
- css - Transform 使用 css 旋转图像并获取要跟随的文本