【问题标题】:Python and GnuCash: Extract data from GnuCash filesPython 和 GnuCash:从 GnuCash 文件中提取数据
【发布时间】:2010-07-31 14:01:54
【问题描述】:

我正在寻找有关如何使用 python 读取 GnuCash 文件的信息。我已经阅读过这个python-gnucash,它提供了与 GnuCash 库的 Python 绑定,但目前需要做很多工作(例如依赖项、标头等)。这些说明是为 Linux 环境和相当旧的 GnuCash 版本 (2.0.x) 量身定制的。我正在运行 GnuCash 2.2.9。虽然我可以操作 Linux 命令行,但我在 Windows XP 上运行 GnuCash。

我的主要目标是读取(还没有计划写入)我的 GnuCash 文件,以便我可以使用 matplotlib 和 @987654325 创建自己的可视化动态报告@。我还没有心情学习 Scheme。

我希望有人能指出我在这方面的良好开端。就我对 GnuCash 和 Python 的了解,我想可能有人知道以下几种解决方案:

  1. 除了this one from the GnuCash wiki 之外,最近更新的文档
  2. 一些解决方法,例如导出到某种文件格式,对于该文件格式,有一个更成熟的 Python 库可以读取它。

除了上面提到的,你们可能还有更好的建议。

【问题讨论】:

    标签: python api matplotlib


    【解决方案1】:

    我发布了 piecash,这是一个使用 SQLAlchemy 作为基础的 SQL 保存 GnuCash 书籍的 Python 接口 (https://github.com/sdementen/piecash)。

    有了它,您可以轻松访问一本书中包含的所有信息。

    例如,遍历书中的所有帐户:

    from piecash import open_book
    
    # open a book
    with open_book("some_book.gnucash", open_if_lock=True) as mybook:
        # iterate over all accounts of the book
        for account in mybook.accounts:
            print(account)
    

    或遍历“资产”帐户中的所有拆分:

    # open the book
    with open_book("some_book.gnucash", open_if_lock=True) as mybook:
        # retrieve the account by its fullname
        asset = mybook.accounts(fullname="Asset")
        # iterate over all its splits
        for split in asset.splits:
            print(split)
    

    最近的版本还允许将拆分信息直接提取到 pandas DataFrames,以便于绘图/分析

    from piecash import open_book
    
    # open a book
    with open_book("some_book.gnucash", open_if_lock=True) as mybook:
        # extract all split information to a pandas DataFrame
        df = mybook.splits_df()
    
        # print for account "Asset" some information on the splits
        print(df.loc[df["account.fullname"] == "Asset",
                     ["transaction.post_date", "value"]])
    

    【讨论】:

    • 这不是投反对票的依据。考虑到用户是 SO 新手。 @sdementen,请注意 Jason 的 cmets,并提供有关如何使用您的库提取数据的详细信息/示例。
    • 到目前为止,这似乎是 Windows 上唯一可用的选项。一个非常好的,在那。
    【解决方案2】:

    GNUCash 2.4 已经发布。

    可以导出为 SQL,因此比解析 XML 容易得多。

    支持 Sqlite、MySQL 和 PostgreSQL(这太酷了!)

    【讨论】:

    • 请告诉我如何激活export to sql功能?我在菜单中找不到它,只有 xml 导出(文件->导出->导出帐户)。我正在使用 Gnucash 2.4.12。
    • 我正在运行 Ubuntu 14.04 打包的 gnucash 2.6。我没有看到导出到 SQL 选项,但我注意到 gnucash 包推荐了我没有安装的 libdbd-{mysql,pgsql,sqlite} 包。添加这些使导出选项出现在界面中。所以有一个带有 Python 模板和 perl 数据绑定的编译可执行文件。奇怪。
    • sudo apt-get install libdbd-sqlite3 在 Ubuntu 中获取 GnuCash 2.6 中的 mysql 功能。然后在 GnuCash 中打开你的书并选择“文件”->“另存为...”并选择“mysql”作为数据格式。
    【解决方案3】:

    您是在谈论数据文件吗?从那里wiki,看起来它们只是压缩的 XML 文件。使用 Python,您可以使用 gzip module 解压缩它们,然后使用任何 available XML parsers 解析它们。

    元素树示例

    >>> import xml.etree.cElementTree as ET
    >>> xmlStr = '''<?xml version="1.0" encoding="UTF-8" ?>
    <painting>
    <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
    <caption>This is Raphael's "Foligno" Madonna, painted in
         <date>1511</date>?<date>1512</date>.
    </caption>
    </painting>
    '''
    >>> tree = ET.fromstring(xmlStr)  #use parse or iterparse to read direct from file path
    >>> tree.getchildren()
    [<Element 'img' at 0x115efc0>, <Element 'caption' at 0x1173090>]
    >>> tree.getchildren()[1].text
    'This is Raphael\'s "Foligno" Madonna, painted in\n    '
    >>> tree.getchildren()[0].get('src')
    'madonna.jpg'
    

    【讨论】:

    • +1 谢谢!这看起来不错。我已经设法用gzip 模块解压它。我尝试使用示例 (Expat) 看到的第一个 XML 解析器,但不幸的是,我无法解析出标签和内容。你能推荐我应该使用哪个 XML 解析器,或者至少可以开始使用吗?
    • @Kit,我在标准库中最喜欢的是 cElementTree (docs.python.org/library/xml.etree.elementtree.html)。确保使用 cElementTree 而不是 ElementTree(前者是用 C 编写的,后来是纯 python)以获得额外的速度。请参阅上面的编辑以快速入门。
    • 这很棒。在处理{URI}tag 格式的命名空间时,我仍然很困惑。无论如何,这将是另一个问题的主题。感谢您的帮助:)
    • 我刚刚发现lxml.etreehandling namespaces 做得更好。
    【解决方案4】:

    我在我编写的 django 应用程序中采用了 sqlite 方法来做类似的事情(尽管用于预算)。代码见https://github.com/evandavey/OpenBudget/blob/master/openbudgetapp/management/commands/gnucash-import.py

    就数据本身而言,我使用 pandas 库来处理其时间序列性质。

    【讨论】:

    • 曾经可能有用,但现在链接已损坏。
    【解决方案5】:

    正如 Chop Suey 所说,GnuCash 2.4 有自己的数据库格式。如果您仍想使用 XML 文件,可以使用以下脚本将 XML 转换为数据库,然后在其上编写报告(例如 gnucashconvert filename.gnucash sqlite3:////home/username/export.sqlite ):

    #!/usr/bin/env python
    
    import os
    import gnucash
    
    def convert_gnucash(src_uri, target_uri):
        """Converts gnucash databases at the given uris from src to target"""
        session = gnucash.Session(src_uri)
        try:
            new_session = gnucash.Session(target_uri, is_new=True)
            try:
                new_session.swap_data(session)
                new_session.save()
            finally:
                new_session.end()
                new_session.destroy()
        finally:
            session.end()
            session.destroy()
    
    if __name__ == "__main__":
        import sys
        if len(sys.argv) > 2:
            src_uri, target_uri = sys.argv[1], sys.argv[2]
            src_uri = ("xml://%s" % os.path.abspath(src_uri) if "://" not in src_uri else src_uri)
            target_uri = ("xml://%s" % os.path.abspath(target_uri) if "://" not in target_uri else target_uri)
            convert_gnucash(src_uri, target_uri)
        else:
            print >>sys.stderr, "Syntax %s src target" % (sys.argv[0])
    

    【讨论】:

      【解决方案6】:

      我刚刚发布了一些 python 代码,可以读取和解释 gnucash 2.6 及更高版本中使用的 sqlite3 文件格式:

      https://github.com/MatzeB/pygnucash

      【讨论】:

      • sqlite 是一个选项,仅在存在 perl 数据绑定库时才存在。
      猜你喜欢
      • 2014-11-02
      • 2016-11-24
      • 2015-12-03
      • 2020-08-23
      • 2015-08-28
      • 2018-03-12
      • 2013-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多