首页 > 解决方案 > 在 SQLAlchemy (sqlite) 中从一个较大的数据库创建一个较小的数据库

问题描述

我想从给定的一个较大的数据库开始创建一个较小的数据库,并且我想用 sqlalchemy 在 python 中完成这一切。

这是我到目前为止所拥有的:我正在查询原始数据库并在两个表(书籍和 anatit)上执行连接以过滤掉数据(原始数据库中还有更多我不需要的表)。我还希望将 market_trades 表包含在较小的数据库中。

engine = create_engine('sqlite:///D:/backtest_dbs/20191016_MIT.db')
conn=engine.connect()
metadata= MetaData()
books=Table('books',metadata, autoload=True, autoload_with=engine)
anatit=Table('anatit',metadata, autoload=True, autoload_with=engine)
market_trades=Table('market_trades',metadata, autoload=True, autoload_with=engine)
stmt=select([books,anatit.columns.CS,anatit.columns.isin,anatit.columns.desc])
stmt=stmt.select_from(anatit.join(books,anatit.columns.CS==books.columns.CS)).where(anatit.columns.desc.like('%BTP%'))
result_proxy=conn.execute(stmt)

但是,在执行该语句后,我不确定如何继续使用 ResultProxy。大小约为 250 万行,所以我for不确定.insert(). 我首先创建另一个引擎,在另一个文件夹中创建较小的数据库。什么是创建表的最佳(在这种情况下,“最佳”意味着 pythonic/高效)方式,我们可以从 ResultProxy 开始,而不必在之后填充它们吗?那么 market_trades 表呢,我可以用autoload_with=engine它来添加它enigne_small吗?

engine_small = create_engine('sqlite:///D:/backtest_dbs/small/20191016_MIT_small.db')
conn=engine_small.connect()
books=Table('books',metadata,...) # What goes in here?
anatit=Table('anatit',metadata,... )
market_trades=Table('market_trades',...) # Can I use autoload_with=engine, the larger db?
metadata.create_all(engine_small)

我知道还有其他不使用 SQLAlchemy 的方法,但我认为这将是一个很好的练习和示例,而且我在这个特定项目中用 python 做所有事情,我希望它保持这种状态。但是,如果有人认为有更好的解决方案可以完全避免使用 SQLAlchemy,我很乐意倾听。

标签: pythonsqlitesqlalchemy

解决方案


对于那些有兴趣的人,当你有 10^6 个数据点时,你可以使用 pandas(特别是如果,比如我的例子,你也想直接访问数据进行分析),这需要几秒钟。

    engine = create_engine('sqlite:///D:/backtest_dbs/20191016_MIT.db')
    conn=engine.connect()
    metadata= MetaData()
    books=Table('books',metadata, autoload=True, autoload_with=engine)
    anatit=Table('anatit',metadata, autoload=True, autoload_with=engine)
    market_trades=Table('market_trades',metadata, autoload=True, autoload_with=engine)
    stmt=select([books,anatit.columns.CS,anatit.columns.isin,anatit.columns.desc])
    stmt=stmt.select_from(anatit.join(books,anatit.columns.CS==books.columns.CS)).where(anatit.columns.desc.like('%BTP%'))
    result_proxy=conn.execute(stmt)
    db_small=pd.DataFrame(result_proxy.fetchall())
    stmt2=select([market_trades])
    result_proxy2=conn.execute(stmt2)
    trades_df=pd.DataFrame(result_proxy2.fetchall())    
    engine_small = create_engine('sqlite:///D:/backtest_dbs/small/20191016_MIT_small.db', echo=True)
    trades_df.to_sql('market_trades', con=engine_small)
    db_small.to_sql('books', con=engine_small)
    result_proxy.close()
    result_proxy2.close()
    conn.close()

这里好的部分是.to_sql()我不知道的方法。您还可以将小型数据库作为数据框访问,因此您可以根据需要进行修改/分析。

如果有人想添加东西,想知道更多(参见原始问题的最后一部分)。


推荐阅读