URI 字符串

Odo 使用字符串来引用 Python 之外的数据。

一些 URI 示例包括以下内容

myfile.json
myfiles.*.csv'
postgresql://hostname::tablename
mongodb://hostname/db::collection
ssh://user@host:/path/to/myfile.csv
hdfs://user@host:/path/to/myfile.csv

odo 支持哪些类型的 URI?

  • 磁盘上的文件路径
    • .csv
    • .json
    • .txt/log
    • .csv.gz/json.gz
    • .hdf5
    • .hdf5::/datapath
    • .bcolz
    • .xls(x)
    • .sas7bdat
  • 磁盘上的文件集合
    • *.csv
  • SQLAlchemy 字符串
    • sqlite:////absolute/path/to/myfile.db::tablename
    • sqlite:////absolute/path/to/myfile.db (指定一个特定的表)
    • postgresql://username:password@hostname:port
    • impala://hostname (使用 impyla
    • 任何 SQLAlchemy 支持的内容
  • MongoDB 连接字符串
    • mongodb://username:password@hostname:port/database_name::collection_name
  • 通过 SSH、HDFS 和 Amazon S3 的远程位置
    • ssh://user@hostname:/path/to/data
    • hdfs://user@hostname:/path/to/data
    • s3://path/to/data

使用 :: 分隔部分

许多数据形式都有两条路径,一条是文件路径,另一条是文件内部的路径。例如,我们像这样引用 Postgres 数据库中的 accounts

postgresql://::accounts

在这种情况下,分隔符 :: 将数据库 postgreqsl:// 与数据库中的表 accounts 分开。

这也发生在具有内部数据路径的 HDF5 文件中

myfile.hdf5::/path/to/data

使用 :// 指定协议

数据库字符串 sqlite:///data/my.db 是 SQLAlchemy 特有的,但遵循一种常见的格式,即

Protocol:  sqlite://
Filename:  data/my.db

Odo 在许多情况下也使用协议来提供关于如何处理您的数据的额外提示。例如,Python 有几个不同的库来处理 HDF5 文件(h5pypytablespandas.HDFStore)。默认情况下,当我们看到像 myfile.hdf5 这样的 URI 时,我们目前使用 h5py。要覆盖此行为,您可以指定一个协议字符串,例如

hdfstore://myfile.hdf5

以指定您要使用特殊的 pandas.HDFStore 格式。

注意: sqlite 字符串有点奇怪,默认情况下它们使用三个斜杠(例如 sqlite:///my.db),而使用绝对路径时则使用四个斜杠(例如 sqlite:////Users/Alice/data/my.db)。

工作原理

我们通过一组正则表达式来匹配 URI。这由 resource 函数处理。

>>> from odo import resource
>>> resource('sqlite:///data.db::iris')
Table('iris', MetaData(bind=Engine(sqlite:///myfile.db)), ...)

当我们在 odo 中使用字符串时,这实际上只是调用 resource 的简写。

>>> from odo import odo
>>> odo('some-uri', list)            # When you write this
>>> odo(resource('some-uri'), list)  # actually this happens

值得注意的是,URI 只是语法糖,您不必使用它们。您总是可以显式地构造对象。Odo 很少发明新类型,而是倾向于使用 Python 生态系统中的标准项目,例如 sqlalchemy.Tablepymongo.Collection。如果您的应用程序也使用这些类型,那么 odo 很可能已经与您的数据兼容。

我可以将其扩展到我自己的类型吗?

当然可以。让我们创建一个小小的资源函数来加载 pickle 文件。

import pickle
from odo import resource

@resource.register('.*\.pkl')  # match anything ending in .pkl
def resource_pickle(uri, **kwargs):
    with open(uri) as f:
        result = pickle.load(f)
    return result

您可以为自己的数据类型实现这种函数。在这里,我们只是将对象加载到内存中并返回它,这是一个相当简单的解决方案。通常,我们会返回一个具有特定类型的对象,该对象能很好地表示该数据。