Feast PostgreSQL 数据源实战:PostgreSQLSource 配置、类型映射与 Point-in-Time Join 实现解析

发布时间:2026/11/7 15:43:33

Feast PostgreSQL 数据源实战:PostgreSQLSource 配置、类型映射与 Point-in-Time Join 实现解析 Feast PostgreSQL 数据源实战PostgreSQLSource 配置、类型映射与 Point-in-Time Join 实现解析【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feastFeast 中的 PostgreSQL 批量数据源PostgreSQLSource允许你直接把 Postgres 表或视图作为特征数据的来源既可以通过表名引用也可以通过任意 SQL 查询定义。本篇围绕该数据源的官方参考文档展开补全其全部构造参数、仓库级连接配置feature_store.yaml与PostgreSQLConfig、类型支持矩阵并结合源码解析 Feast 如何基于该数据源生成 Point-in-Time Join SQL、执行特征检索与类型映射帮助你在 Feast 仓库中实际搭建以 PostgreSQL 为后端离线存储的批量特征管道。一、PostgreSQL 数据源是什么PostgreSQL 数据源在 Feast 中由PostgreSQLSource类实现位于 postgres_source.py。它表示的是一张PostgreSQL 表或视图有两种指定方式表引用table reference通过table参数直接给出表名SQL 查询SQL query通过query参数给出任意 SELECT 查询适合从多表 JOIN、过滤或聚合后的结果上取特征。官方参考文档位于 postgres.md其中给出了最简的查询式定义示例from feast.infra.offline_stores.contrib.postgres_offline_store.postgres_source import ( PostgreSQLSource, ) driver_stats_source PostgreSQLSource( namefeast_driver_hourly_stats, querySELECT * FROM feast_driver_hourly_stats, timestamp_fieldevent_timestamp, created_timestamp_columncreated, )该示例与仓库中 Postgres 模板 feature repo 的完整定义feature_definitions.py一致模板中进一步将该数据源绑定到一个带ttltimedelta(days1)、onlineTrue的FeatureViewdriver_hourly_stats并组合进FeatureService展示了从数据源到特征视图、再到在线服务的完整链路。稳定性说明官方原文警示参考文档明确声明 The PostgreSQL data source does not achieve full test coverage. Please do not assume complete stability.PostgreSQL 数据源未达到完整测试覆盖请勿假设其完全稳定。此外数据源总览 的功能矩阵也将PostgreSQLSource归类为社区贡献contrib实现与FileSource、BigQuerySource、SnowflakeSource、RedshiftSource等核心实现并列但稳定性不作保证。生产使用前建议在 CI 中加入自己的回归验证。二、PostgreSQLSource 完整参数说明PostgreSQLSource的构造签名见 postgres_source.py#L28-L40完整参数如下参数类型 / 默认值说明nameOptional[str]默认None数据源名称项目内需唯一。若未提供name但提供了table则以表名作为默认名称name与table同时为空会抛出DataSourceNoNameExceptionqueryOptional[str]默认None用于取数的 SQL 查询语句与table二选一的取数方式tableOptional[str]默认None表名与query二选一的取数方式timestamp_fieldOptional[str]默认事件时间戳字段用于 Point-in-Time Join 中选取事件时间点的特征值created_timestamp_columnOptional[str]默认行创建时间戳列用于对同一事件时间点的重复行去重保留创建时间最新的一行field_mappingOptional[Dict[str, str]]数据源列名到特征名的映射仅作用于特征列不作用于实体列或时间戳列descriptionOptional[str]人类可读的描述tagsOptional[Dict[str, str]]任意键值对元数据ownerOptional[str]数据源负责人通常是主要维护者的邮箱connection_refOptional[ConnectionRef]为该数据源单独指定外部凭据引用见下文类上还实现了两个值得注意的方法get_table_column_names_and_types(config)通过SELECT * FROM {表/查询} AS sub LIMIT 0执行零行查询利用游标的description拿到列名与 Oid 类型码再经pg_type_code_to_pg_type映射为 PostgreSQL 类型名postgres_source.py#L137-L148__eq__/__hash__除基类字段外还比较query、timestamp_field、created_timestamp_column、field_mapping保证注册表中相同数据源对象可正确判等。三、表引用与 SQL 查询子查询别名问题Postgres 要求FROM子句中的所有子查询必须带别名这是 query 式数据源最容易踩的坑。PostgreSQLSource为此提供了两个方法postgres_source.py#L150-L188def get_table_query_string(self) - str: 表式来源返回表名查询式来源返回带括号的查询 (query) def get_table_query_string_with_alias(self, alias: str subquery) - str: 表式来源原样返回表名查询式来源返回 (query) AS aliastable式来源两者行为一致直接返回表名query式来源前者返回(SELECT ...)后者返回(SELECT ...) AS subquery。从源码结构看Feast 内部取全量/最新数据pull_all_from_table_or_query与计算监控指标时会显式追加别名例如FROM {from_expression} AS paftoq_aliaspostgres.py#L294-L324、FROM {from_expression} AS max_ts_aliaspostgres.py#L400-L405避免手写 SQL 时忘记别名导致syntax error。如果你基于该数据源自建查询建议统一使用get_table_query_string_with_alias()。四、仓库级配置feature_store.yaml 与连接参数数据源本身不携带连接信息连接参数来自feature_store.yaml的offline_store配置。仓库中的 Postgres 模板给出了标准写法feature_store.yamlproject: my_project provider: local registry: registry_type: sql path: postgresql://DB_USERNAME:DB_PASSWORDDB_HOST:DB_PORT/DB_NAME?sslmodeDB_SSLMODE cache_ttl_seconds: 60 sqlalchemy_config_kwargs: echo: false pool_pre_ping: true online_store: type: postgres host: DB_HOST port: DB_PORT database: DB_NAME db_schema: DB_SCHEMA user: DB_USERNAME password: DB_PASSWORD sslmode: DB_SSLMODE offline_store: type: postgres host: DB_HOST port: DB_PORT database: DB_NAME db_schema: DB_SCHEMA user: DB_USERNAME password: DB_PASSWORD sslmode: DB_SSLMODE entity_key_serialization_version: 3offline_store段由 postgres_config.py 中的PostgreSQLConfig解析完整字段及默认值如下字段默认值说明host必填数据库主机port5432端口database必填数据库名db_schemapublic目标 schema。连接时会注入options-c search_path{schema},public因此 schema 内的表无需带前缀即可访问见 connection_utils.py#L69-L80user/password必填认证信息sslmoderequireSSL 模式默认强制 SSLsslkey_path/sslcert_path/sslrootcert_pathNone客户端证书与 CA 证书路径min_conn/max_conn1/10连接池的最小/最大连接数conn_typesingleton连接模式singleton单连接或pool连接池keepalives_idleNoneTCP keepalive 空闲秒数底层通过psycopgv3建连_get_conn()使用make_conninfo拼装conninfo字符串并支持同步/异步连接与ConnectionPool连接池connection_utils.py#L15-L54。PostgreSQLOfflineStoreConfig在PostgreSQLConfig之上还增加了一个离线存储专属选项postgres.py#L72-L74class PostgreSQLOfflineStoreConfig(PostgreSQLConfig): type: Literal[postgres] postgres entity_select_mode: EntitySelectMode EntitySelectMode.temp_tableentity_select_mode控制历史特征检索时实体 DataFrame / 实体 SQL 的处理方式temp_table默认把实体 DataFrame 上传为 Postgres 临时表或把实体 SQL 物化为表查询完成后自动DROP TABLE IF EXISTSembed_query仅当实体输入是 SQL 字符串时生效直接以 CTEWITH entity_query AS (...)形式内联进检索 SQL省去建表开销。凭据隔离ConnectionRef参考文档提到的完整配置选项中包含connection_ref。根据数据源总览ConnectionRef允许每个数据源声明自己的外部凭据引用Kubernetes Secrets、HashiCorp Vault、环境变量等用于多租户部署与凭据隔离有connection_ref时凭据在运行时从外部提供者解析并覆盖全局 offline store 配置没有时回落到feature_store.yaml。PostgreSQLSource构造函数与from_proto反序列化均接受connection_refpostgres_source.py#L39。五、类型支持参考文档声明 PostgreSQL 数据源支持全部 8 种原始类型及其对应数组类型。结合 overview.md 的功能矩阵Postgres 列的支持情况为bytes、string、int32、int64、float32、float64、bool、timestamp均为 yes数组类型为 yes额外还支持Mapjson/jsonb、Json与Struct。映射关系定义在 type_map.py 中pg_type_to_feast_value_typetype_map.py#L2042把 Postgres 类型名映射为 FeastValueType例如integer/smallint→INT32、bigint→INT64、real→FLOAT、double precision→DOUBLE、timestamp with time zone/timestamp without time zone/date→UNIX_TIMESTAMP、json/jsonb→MAP、uuid→UUID以及各类[]数组类型到*_LIST的映射pg_type_code_to_pg_typetype_map.py#L2140把游标返回的 Oid 类型码如 23→integer、1184→timestamp with time zone、3802→jsonb还原为类型名。从源码结构看对未知类型码它不抛异常而是返回unknownFeast 会跳过问题列并打印警告——这一点在含自定义类型的库中要留意pg_type_code_to_arrow则用于检索结果直接构建 PyArrow schemafeast_value_type_to_pa保证 Arrow 列类型与 Postgres 类型一致。六、检索实现Point-in-Time Join 是如何生成的PostgreSQLOfflineStorepostgres.py声明supports_filter_by_created_timestamp True即该数据源支持按created_timestamp_column过滤与数据源定义中的created_timestamp_column参数呼应。核心检索路径有两条1. 单视图取数pull_latest / pull_allpull_latest_from_table_or_querypostgres.py#L80-L150在时间窗BETWEEN {start_date}::timestamptz AND {end_date}::timestamptz内优先用 Postgres 特有的SELECT DISTINCT ON (join_keys)按实体取每实体最新一行若指定了created_timestamp_column排序键追加created DESC实现重复行去重pull_all_from_table_or_querypostgres.py#L281-L331默认物化路径按get_timestamp_filter_sql生成时间过滤后整表拉取当feature_name_columns为空BatchFeatureView 的 python/pandas/ray 转换信号时退化为SELECT *避免只选 join key 时间戳导致 UDF 缺少输入特征。2. 多视图历史特征get_historical_featuresget_historical_featurespostgres.py#L152-L279的调用链为推断实体时间戳列并计算实体时间戳范围非实体无 entity_df检索时自动合成仅含end_date的合成实体行依据entity_select_mode决定temp_table物化或embed_queryCTE用 Jinja2 渲染MULTIPLE_FEATURE_VIEW_POINT_IN_TIME_JOIN模板postgres.py#L809 起。模板注释明确说明其改编自 Feast Redshift 离线存储实现。该模板生成的 SQL 结构是典型的 Feast 时间旅行连接entity_dataframeCTE对每个特征视图计算entity_row_unique_id实体列与时间戳拼接的确定性标识{{view}}__subquery先用timestamp_field MAX(entity_timestamp)与 TTL 下界entity_timestamp - ttl * interval 1 second粗筛{{view}}__baseINNER JOIN 实体逐行保证event_timestamp entity_timestamp且满足 TTL若开启filter_by_created_timestamp还附加created_timestamp entity_timestamp条件{{view}}__dedup/{{view}}__latest基于created_timestamp做MAX去重后用ROW_NUMBER() OVER (PARTITION BY entity_row_unique_id ORDER BY event_timestamp DESC, created_timestamp DESC)取每实体每时间点唯一最新行最终按entity_row_unique_id把各视图结果 LEFT JOIN 回实体表得到与实体行对齐的训练数据。3. 结果物化PostgreSQLRetrievalJob所有检索最终包装为PostgreSQLRetrievalJobpostgres.py#L603-L684_to_arrow_internal以read_onlyTrue执行查询从游标description推断 Arrow 字段类型按列转置后构建pa.Table再转 pandas查询零列时会抛出ZeroColumnQueryResultpersist()借助SavedDatasetPostgreSQLStorage把结果写回 Postgres 表df_to_postgres_table会按 Arrow 类型推导CREATE TABLE语句并executemany插入。此外该离线存储还内置了 SQL 下推的监控指标能力compute_monitoring_metrics用单条聚合 SQL 批量计算数值特征的mean/stddev/min/max/p50~p99PERCENTILE_CONT分位数 width_bucket直方图与分类特征的 Top-N 分布并通过INSERT ... ON CONFLICT DO UPDATE把指标 upsert 到ensure_monitoring_tables创建的原生监控表postgres.py#L1108-L1300。七、实战建议与小结优先用table指向物化好的视图/表query 式来源会以内联子查询进入所有生成的 SQL物化、检索、监控大查询应确保自身索引完备timestamp_field用timestamptz检索 SQL 统一以::timestamptz强转时间边界naive timestamp 与 timestamptz 混用容易引入时区偏差多实体视图去重依赖created_timestamp_column若源表存在同一事件时间点的重复写入务必设置该列以获得确定性去重关注稳定性声明官方文档与功能矩阵均提示该 contrib 数据源无完整测试覆盖单元测试位于 test_postgres.py关键链路建议纳入自有回归schema 与 SSLdb_schema通过search_path生效、sslmode默认require跨 schema 或内网自签证书环境需显式配置sslrootcert_path等字段。综上Feast 的 PostgreSQL 数据源以PostgreSQLSource表或 SQL 查询为入口通过feature_store.yaml的offline_store段完成连接配置类型系统经 Oid 类型码—Postgres 类型名—Feast ValueType 两级映射对齐检索层利用DISTINCT ON与ROW_NUMBER窗口函数在 Postgres 内完成 Point-in-Time Join并以 Arrow 管道物化结果。理解上述参数与 SQL 生成逻辑后即可在 Feast 中把任意可查询的 Postgres 表/视图接入批量特征管道。【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/5 21:57:55

线程调度器全解析:从CFS、时间片到负载与学习率调度

线程管理这条线,前两篇我们聊了线程的创建与同步,到了第三篇,绕不开的就是调度器。说白了,线程本身不会自己动,谁来分配 CPU 时间、谁来决定下一个跑谁、一个线程能让出多少次执行机会,全由调度器说了算。很…

2026/11/3 17:03:44

Phinger Cursors 项目教程

Phinger Cursors 项目教程 【免费下载链接】phinger-cursors Most likely the most over engineered cursor theme. 项目地址: https://gitcode.com/gh_mirrors/ph/phinger-cursors 1. 项目介绍 Phinger Cursors 是一个高度工程化的鼠标指针主题项目,旨在为…

2026/11/7 15:39:52

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了 你缺一张电工证,别人就多一份机会。在曹县,找电工相关的工作,电工证几乎是 硬性门槛 ,没有它,连面试资格都没有。尤其是现在企业招聘越来越规范,特种作业证成了“门槛证”,没有它,…

2026/11/7 15:39:52

曹县电工证在哪里考值不值得考

曹县电工证在哪里考值不值得考 之前考的证在外省能不能转过来?这是很多电工朋友心头的疑问。特别是在曹县,有些人在外地打工多年,考了电工证,回来之后却发现手续繁琐,甚至不知从何下手。 值不值得考…

2026/11/7 15:39:52

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定 实操考试心里没底怕挂科?你不是一个人。特别是像我们平顶山市从事市政公用工程的朋友,高压电工证不仅是从业门槛,更是日常操作的“安全锁”。很多人在报名时对流程不清楚,对考试内容不…

2026/11/7 15:39:52

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑 不知道去哪报名怕被中介坑,是很多初次报考建筑特种工和技术工的新人最真实的困扰。我自己当初也是在朋友介绍下,稀里糊涂地交了钱,结果证书还没拿到,钱就打水漂了。今天我就从一个过来人的角度,把…

2026/11/7 15:39:52

电工证能在异地年检吗 30天拿证攻略全解析

电工证能在异地年检吗 30天拿证攻略全解析 急需特种作业证才能上岗找工作,电工证作为高需求证书之一,不仅关系到能否入职,还直接决定了薪资水平和发展空间。不少朋友问: 电工证能在异地年检吗 ?更有人担心 多久拿证…

2026/11/7 15:34:51

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解 证书过期了不知道怎么复审延期?你不是一个人,很多郑州市政公用工程从业者都遇到过这个问题。别急,下面一步步告诉你怎么搞定硬件施工电工证的复审和延期,确保你随时“上岗必备”,不掉链…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑