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::tablenamesqlite:////absolute/path/to/myfile.db(指定一个特定的表)postgresql://username:password@hostname:portimpala://hostname(使用impyla)- 任何 SQLAlchemy 支持的内容
- MongoDB 连接字符串
mongodb://username:password@hostname:port/database_name::collection_name
- 通过 SSH、HDFS 和 Amazon S3 的远程位置
ssh://user@hostname:/path/to/datahdfs://user@hostname:/path/to/datas3://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 文件(h5py、pytables、pandas.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.Table 或 pymongo.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
您可以为自己的数据类型实现这种函数。在这里,我们只是将对象加载到内存中并返回它,这是一个相当简单的解决方案。通常,我们会返回一个具有特定类型的对象,该对象能很好地表示该数据。