我有两个对象列表: listA<modelA>(), listB<modelB>()
基于以下模型。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class modelA(Base):
__tablename__ = "TableA"
rowID = Column(Integer, primary_key=True)
applicationNo = Column(String)
accountNum = Column(String)
sanitizedAccountNum = Column(String)
class modelB(Base):
__tablename__ = "TableB"
rowID = Column(Integer, primary_key=True)
applicationNo = Column(String)
accountNum = Column(String)
sanitizedAccountNum = Column(String)
# create SQLAlchemy engine/connection
engine = create_engine("mysql+mysqlconnector://root:usbw@localhost:3307/testDB", echo=False)
dbSession = sessionmaker(bind=engine)
session = dbSession()
# query to pull data from DB
listA = session.query(modelA).limit(100).all()
listB = session.query(modelB).limit(100).all()
这些列表是使用sqlalchemy填充的。每个表都包含将近一百万条记录,因此我尝试一次对一部分记录执行查询。
从数据库中获取数据后,我尝试对上面的两个列表执行sql样式的左联接,如下面的sql查询:
SELECT a.applicationNo, a.sanitizedAccountNum
FROM listA a
LEFT JOIN listB b on b.applicationNo=a.applicationNo and b.sanitizedAccountNum=a.sanitizedAccountNum
WHERE b.applicationNo IS NULL;
我已经尝试使用Pandas的Dataframe,但无法得到正确的结果。
Pandas:
dfA = pd.DataFrame(listA)
dfB = pd.DataFrame(listB)
resultPD = pd.merge(dfA, dfB, how="left"), on=["applicationNo","sanitizedAccountNum"])
这里的“on”子句不能给我“keyerror:'applicationno'”。如何为我的模型设置上述查询中的“join on”列?
回溯:
Traceback (most recent call last):
File "dbna.py", line 58, in <module>
resultPD = pd.merge(dfA, dfB, indicator="i", how="left", on=["applicationNo","sanitizedAccountNum"])
File "C:\Users\1833\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\reshape\merge.py", line 61, in merge validate=validate)
File "C:\Users\1833\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\reshape\merge.py", line 551, in __init__ self.join_names) = self._get_merge_keys()
File "C:\Users\1833\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\reshape\merge.py", line 857, in _get_merge_keys rk, stacklevel=stacklevel))
File "C:\Users\1833\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\generic.py", line 1382, in _get_label_or_level_values raise KeyError(key)
KeyError: 'applicationNo'
另外,这是“左连接”lista和listb并根据上面提到的两个特定列仅从lista获取那些不在listb中的记录的最佳方法吗?
编辑(示例数据):表格示例
表B样品
更新:
正如@philip在下面的评论中所建议的,诀窍是直接将db结果绑定到pandasDataframe,而不是绑定到类(模型)的列表,然后从该列表创建一个Dataframe。他在评论中提供的这个链接起了作用。
1条答案
按热度按时间pkbketx91#
一个建议是,您可以在mysql中或作为查询创建一个视图,然后使用具有记录限制的视图,或者在pandas中指定chunksize。
在数据库中创建视图:
在pandas中使用query1:
或者直接在pandas中使用query2:
然后用Pandas来阅读chunksize,做你喜欢的事情,把不同的chunksize合并在一起。
您可以在这里找到有关pandas.read\u sql\u查询的更多信息
另一个建议是直接使用sqlalchemy创建视图,并执行上面所做的操作。在我看来,选择取决于项目的目的。您可能会在这里找到在sqlalchemy中创建视图的灵感
你的第一个问题。我认为查询应该是这样的:
你的第二个问题。左连接是只从lista获取不在listb中的记录的方法。您还使用了where子句,该子句添加了应选择哪些行的附加规则。
更新i
我刚意识到你的数据是以字符串的形式存储的。在字符串值上连接数据不是好的做法。如果可能的话,我建议将存储为字符串的数字转换为整数。这有助于避免很多问题。
更新ii-添加数据
我试过用你截屏的数据。每行用两行就行了。
有了以上这些,我就可以得到一个resultpd了。