Python 和 GnuCash:从 GnuCash 文件中提取数据

问题描述 投票:0回答:6

我正在寻找有关如何使用 python 读取 GnuCash 文件的信息。我已经读过这个

python-gnucash
,它提供了与 GnuCash 库的 Python 绑定,但目前需要做很多工作(例如依赖项、标头等)。这些说明是针对 Linux 环境和相当旧的 GnuCash 版本 (2.0.x) 定制的。我正在运行 GnuCash 2.2.9。虽然我可以操作 Linux 命令行,但我在 Windows XP 上运行 GnuCash。

我的主要目标是阅读(尚未计划)我的GnuCash 文件,以便我可以使用

matplotlib
wxpython
创建自己的可视化动态报告。我还没心情学Scheme。

我希望有人能指出我在这方面有一个良好的开端。据我对 GnuCash 和 Python 的了解,我认为有人可能知道以下类型的解决方案:

  1. 除了 来自 GnuCash wiki 的文档之外,还有最近更新的文档
  2. 一些解决方法,例如导出为某种文件格式,有更成熟的 Python 库可以读取它。

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

python api matplotlib gnucash piecash
6个回答
9
投票

我发布了 piecash,这是一个 SQL 保存的 GnuCash 书籍的 Python 接口,它使用 SQLAlchemy 作为基础 (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"]])

6
投票

GNUCash 2.4 已发布。

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

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


4
投票

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

元素树示例

>>> 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
投票

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

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


1
投票

正如 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])

1
投票

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

https://github.com/MatzeB/pygnucash

© www.soinside.com 2019 - 2024. All rights reserved.