|
| 1 | +# 检查多Owner继承问题 |
| 2 | + |
| 3 | +## 🔍 问题诊断步骤 |
| 4 | + |
| 5 | +您说仍然只有一个人,让我们逐步检查问题: |
| 6 | + |
| 7 | +### 步骤 1: 确认代码修改已生效 |
| 8 | + |
| 9 | +```bash |
| 10 | +cd ~/workspaces/OpenMetadata |
| 11 | + |
| 12 | +# 检查 common_db_source.py 的修改 |
| 13 | +grep -A 5 "Store ALL owner names" ingestion/src/metadata/ingestion/source/database/common_db_source.py |
| 14 | + |
| 15 | +# 应该看到: |
| 16 | +# database_owner_names = [owner.name for owner in database_owner_ref.root] |
| 17 | +``` |
| 18 | + |
| 19 | +**期望输出**: |
| 20 | +```python |
| 21 | +# Store ALL owner names (support multiple owners for inheritance) |
| 22 | +database_owner_names = [owner.name for owner in database_owner_ref.root] |
| 23 | +# If only one owner, store as string; otherwise store as list |
| 24 | +database_owner = database_owner_names[0] if len(database_owner_names) == 1 else database_owner_names |
| 25 | +``` |
| 26 | + |
| 27 | +如果**没有看到**这个,说明修改没有保存,请重新应用修改。 |
| 28 | + |
| 29 | +### 步骤 2: 检查 owner_utils.py 的类型声明 |
| 30 | + |
| 31 | +```bash |
| 32 | +grep "parent_owner: Optional" ingestion/src/metadata/utils/owner_utils.py |
| 33 | + |
| 34 | +# 应该看到(2处): |
| 35 | +# parent_owner: Optional[Union[str, List[str]]] = None, |
| 36 | +``` |
| 37 | + |
| 38 | +**期望输出**: |
| 39 | +```python |
| 40 | +parent_owner: Optional[Union[str, List[str]]] = None, # 第56行 |
| 41 | +parent_owner: Optional[Union[str, List[str]]] = None, # 第234行 |
| 42 | +``` |
| 43 | + |
| 44 | +如果还是 `Optional[str]`,说明类型声明没有更新。 |
| 45 | + |
| 46 | +### 步骤 3: 运行带调试日志的 ingestion |
| 47 | + |
| 48 | +```bash |
| 49 | +cd ~/workspaces/OpenMetadata |
| 50 | + |
| 51 | +# 运行测试,开启DEBUG日志 |
| 52 | +metadata ingest -c ingestion/tests/unit/metadata/ingestion/owner_config_tests/test-03-multiple-users.yaml --debug 2>&1 | tee /tmp/ingestion_debug.log |
| 53 | + |
| 54 | +# 搜索继承相关的日志 |
| 55 | +grep -i "inherited\|parent_owner" /tmp/ingestion_debug.log |
| 56 | +``` |
| 57 | + |
| 58 | +**关键日志要点**: |
| 59 | + |
| 60 | +1. **Database 层级**(应该看到2个owners): |
| 61 | +``` |
| 62 | +DEBUG ... Matched owner for 'finance_db' using FQN: ['alice', 'bob'] |
| 63 | +``` |
| 64 | + |
| 65 | +2. **Schema 层级**(应该继承列表): |
| 66 | +``` |
| 67 | +DEBUG ... Using inherited owner for 'accounting': ['alice', 'bob'] |
| 68 | +或 |
| 69 | +DEBUG ... Using inherited owner for 'accounting': alice, bob |
| 70 | +``` |
| 71 | + |
| 72 | +❌ **如果看到的是**: |
| 73 | +``` |
| 74 | +DEBUG ... Using inherited owner for 'accounting': alice |
| 75 | +或 |
| 76 | +DEBUG ... Using inherited owner for 'accounting': ['alice'] |
| 77 | +``` |
| 78 | +说明继承时只传递了一个owner。 |
| 79 | + |
| 80 | +### 步骤 4: 检查实际创建的请求 |
| 81 | + |
| 82 | +在日志中搜索 `CreateDatabaseSchemaRequest`: |
| 83 | + |
| 84 | +```bash |
| 85 | +grep -A 20 "CreateDatabaseSchemaRequest" /tmp/ingestion_debug.log | grep -A 5 "accounting" |
| 86 | +``` |
| 87 | + |
| 88 | +**期望看到**: |
| 89 | +``` |
| 90 | +owners: [ |
| 91 | + EntityReference(name='alice', type='user'), |
| 92 | + EntityReference(name='bob', type='user') |
| 93 | +] |
| 94 | +``` |
| 95 | + |
| 96 | +### 步骤 5: 检查 API 实际存储的数据 |
| 97 | + |
| 98 | +```bash |
| 99 | +# 获取 schema 的 owners |
| 100 | +JWT_TOKEN="your_jwt_token" |
| 101 | + |
| 102 | +curl -s -X GET "http://localhost:8585/api/v1/databaseSchemas/name/postgres-test-03-multiple-users.finance_db.accounting" \ |
| 103 | + -H "Authorization: Bearer $JWT_TOKEN" | jq '.owners' |
| 104 | +``` |
| 105 | + |
| 106 | +**期望输出**(2个owners): |
| 107 | +```json |
| 108 | +[ |
| 109 | + { |
| 110 | + "id": "...", |
| 111 | + "name": "alice", |
| 112 | + "type": "user" |
| 113 | + }, |
| 114 | + { |
| 115 | + "id": "...", |
| 116 | + "name": "bob", |
| 117 | + "type": "user" |
| 118 | + } |
| 119 | +] |
| 120 | +``` |
| 121 | + |
| 122 | +❌ **如果只看到1个**: |
| 123 | +```json |
| 124 | +[ |
| 125 | + { |
| 126 | + "id": "...", |
| 127 | + "name": "alice", |
| 128 | + "type": "user" |
| 129 | + } |
| 130 | +] |
| 131 | +``` |
| 132 | + |
| 133 | +## 🐛 常见问题排查 |
| 134 | + |
| 135 | +### 问题 A: 代码修改没有生效 |
| 136 | + |
| 137 | +**症状**: 检查代码文件,发现还是旧的 |
| 138 | + |
| 139 | +**解决**: |
| 140 | +```bash |
| 141 | +# 重新应用修改 |
| 142 | +cd ~/workspaces/OpenMetadata |
| 143 | + |
| 144 | +# 确认 common_db_source.py 第225-228行 |
| 145 | +sed -n '225,228p' ingestion/src/metadata/ingestion/source/database/common_db_source.py |
| 146 | + |
| 147 | +# 如果不对,重新修改 |
| 148 | +``` |
| 149 | + |
| 150 | +### 问题 B: Python 缓存的 .pyc 文件 |
| 151 | + |
| 152 | +**症状**: 代码改了但运行还是旧逻辑 |
| 153 | + |
| 154 | +**解决**: |
| 155 | +```bash |
| 156 | +cd ~/workspaces/OpenMetadata/ingestion |
| 157 | + |
| 158 | +# 清除所有 .pyc 缓存 |
| 159 | +find . -type f -name "*.pyc" -delete |
| 160 | +find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true |
| 161 | + |
| 162 | +# 重新运行 |
| 163 | +metadata ingest -c tests/unit/metadata/ingestion/owner_config_tests/test-03-multiple-users.yaml |
| 164 | +``` |
| 165 | + |
| 166 | +### 问题 C: OpenMetadata 服务端限制 |
| 167 | + |
| 168 | +**症状**: 日志显示传递了2个owners,但API只返回1个 |
| 169 | + |
| 170 | +**可能原因**: OpenMetadata 服务端可能有限制或bug |
| 171 | + |
| 172 | +**检查**: |
| 173 | +```bash |
| 174 | +# 直接测试 database 的 owners(这个应该是2个) |
| 175 | +curl -s -X GET "http://localhost:8585/api/v1/databases/name/postgres-test-03-multiple-users.finance_db" \ |
| 176 | + -H "Authorization: Bearer $JWT_TOKEN" | jq '.owners | length' |
| 177 | + |
| 178 | +# 期望输出: 2 |
| 179 | +``` |
| 180 | + |
| 181 | +如果 database 只有1个owner,说明问题在更早的阶段。 |
| 182 | + |
| 183 | +### 问题 D: 旧数据残留 |
| 184 | + |
| 185 | +**症状**: 之前运行过测试,数据库中有旧的owner信息 |
| 186 | + |
| 187 | +**解决**: |
| 188 | +```bash |
| 189 | +# 方法1: 删除旧的 service(重新ingestion) |
| 190 | +# 需要通过 UI 或 API 删除 postgres-test-03-multiple-users service |
| 191 | + |
| 192 | +# 方法2: 使用 overrideMetadata (test-03 已配置) |
| 193 | +# 检查 yaml 文件 |
| 194 | +grep overrideMetadata ingestion/tests/unit/metadata/ingestion/owner_config_tests/test-03-multiple-users.yaml |
| 195 | + |
| 196 | +# 应该看到: overrideMetadata: true |
| 197 | +``` |
| 198 | + |
| 199 | +## 📊 快速诊断脚本 |
| 200 | + |
| 201 | +创建一个脚本自动检查: |
| 202 | + |
| 203 | +```bash |
| 204 | +cat > /tmp/check_multi_owner.sh << 'EOF' |
| 205 | +#!/bin/bash |
| 206 | +
|
| 207 | +echo "多Owner继承快速诊断" |
| 208 | +echo "====================" |
| 209 | +echo "" |
| 210 | +
|
| 211 | +# 1. 检查代码修改 |
| 212 | +echo "【1】检查 common_db_source.py 修改:" |
| 213 | +if grep -q "database_owner_names = \[owner.name for owner in database_owner_ref.root\]" ~/workspaces/OpenMetadata/ingestion/src/metadata/ingestion/source/database/common_db_source.py; then |
| 214 | + echo "✅ Database owner 存储逻辑已修改" |
| 215 | +else |
| 216 | + echo "❌ Database owner 存储逻辑未修改(问题在这里!)" |
| 217 | +fi |
| 218 | +
|
| 219 | +if grep -q "schema_owner_names = \[owner.name for owner in schema_owner_ref.root\]" ~/workspaces/OpenMetadata/ingestion/src/metadata/ingestion/source/database/common_db_source.py; then |
| 220 | + echo "✅ Schema owner 存储逻辑已修改" |
| 221 | +else |
| 222 | + echo "❌ Schema owner 存储逻辑未修改(问题在这里!)" |
| 223 | +fi |
| 224 | +
|
| 225 | +echo "" |
| 226 | +
|
| 227 | +# 2. 检查类型声明 |
| 228 | +echo "【2】检查 owner_utils.py 类型声明:" |
| 229 | +if grep -q "parent_owner: Optional\[Union\[str, List\[str\]\]\]" ~/workspaces/OpenMetadata/ingestion/src/metadata/utils/owner_utils.py; then |
| 230 | + echo "✅ parent_owner 类型已更新为 Union[str, List[str]]" |
| 231 | +else |
| 232 | + echo "❌ parent_owner 类型还是 str(问题在这里!)" |
| 233 | +fi |
| 234 | +
|
| 235 | +echo "" |
| 236 | +echo "【3】建议操作:" |
| 237 | +echo " 1. 如果上面有 ❌,重新应用修改" |
| 238 | +echo " 2. 清除 Python 缓存: find ingestion -name '*.pyc' -delete" |
| 239 | +echo " 3. 运行: metadata ingest -c test-03-multiple-users.yaml --debug" |
| 240 | +echo " 4. 检查日志: grep 'inherited' /tmp/ingestion_debug.log" |
| 241 | +EOF |
| 242 | + |
| 243 | +chmod +x /tmp/check_multi_owner.sh |
| 244 | +bash /tmp/check_multi_owner.sh |
| 245 | +``` |
| 246 | + |
| 247 | +## 🔬 深度调试 |
| 248 | + |
| 249 | +如果上面都正常,但还是只有1个owner,添加调试输出: |
| 250 | + |
| 251 | +### 临时修改 common_db_source.py(添加打印) |
| 252 | + |
| 253 | +在第225行后添加: |
| 254 | + |
| 255 | +```python |
| 256 | +# Store ALL owner names (support multiple owners for inheritance) |
| 257 | +database_owner_names = [owner.name for owner in database_owner_ref.root] |
| 258 | +# If only one owner, store as string; otherwise store as list |
| 259 | +database_owner = database_owner_names[0] if len(database_owner_names) == 1 else database_owner_names |
| 260 | + |
| 261 | +# 🔍 临时调试输出 |
| 262 | +print(f"🔍 DEBUG: database_owner_names = {database_owner_names}") |
| 263 | +print(f"🔍 DEBUG: database_owner (stored in context) = {database_owner}") |
| 264 | +print(f"🔍 DEBUG: type = {type(database_owner)}") |
| 265 | + |
| 266 | +self.context.get().upsert("database_owner", database_owner) |
| 267 | +``` |
| 268 | + |
| 269 | +### 临时修改 owner_utils.py(添加打印) |
| 270 | + |
| 271 | +在第117行后添加: |
| 272 | + |
| 273 | +```python |
| 274 | +if self.enable_inheritance and parent_owner: |
| 275 | + # 🔍 临时调试输出 |
| 276 | + print(f"🔍 DEBUG: resolve_owner called with parent_owner = {parent_owner}") |
| 277 | + print(f"🔍 DEBUG: parent_owner type = {type(parent_owner)}") |
| 278 | + |
| 279 | + owner_ref = self._get_owner_refs(parent_owner) |
| 280 | + |
| 281 | + # 🔍 临时调试输出 |
| 282 | + if owner_ref and owner_ref.root: |
| 283 | + print(f"🔍 DEBUG: _get_owner_refs returned {len(owner_ref.root)} owners") |
| 284 | + print(f"🔍 DEBUG: owners = {[o.name for o in owner_ref.root]}") |
| 285 | +``` |
| 286 | + |
| 287 | +然后运行: |
| 288 | + |
| 289 | +```bash |
| 290 | +metadata ingest -c test-03-multiple-users.yaml 2>&1 | grep "🔍 DEBUG" |
| 291 | +``` |
| 292 | + |
| 293 | +**期望看到**: |
| 294 | +``` |
| 295 | +🔍 DEBUG: database_owner_names = ['alice', 'bob'] |
| 296 | +🔍 DEBUG: database_owner (stored in context) = ['alice', 'bob'] |
| 297 | +🔍 DEBUG: type = <class 'list'> |
| 298 | +🔍 DEBUG: resolve_owner called with parent_owner = ['alice', 'bob'] |
| 299 | +🔍 DEBUG: parent_owner type = <class 'list'> |
| 300 | +🔍 DEBUG: _get_owner_refs returned 2 owners |
| 301 | +🔍 DEBUG: owners = ['alice', 'bob'] |
| 302 | +``` |
| 303 | + |
| 304 | +## ✅ 最终验证 |
| 305 | + |
| 306 | +完成所有修改后: |
| 307 | + |
| 308 | +```bash |
| 309 | +# 1. 清除缓存 |
| 310 | +find ~/workspaces/OpenMetadata/ingestion -name "*.pyc" -delete |
| 311 | + |
| 312 | +# 2. 运行测试 |
| 313 | +metadata ingest -c test-03-multiple-users.yaml --debug 2>&1 | tee /tmp/test.log |
| 314 | + |
| 315 | +# 3. 检查关键日志 |
| 316 | +echo "=== 检查继承日志 ===" |
| 317 | +grep "inherited owner" /tmp/test.log |
| 318 | + |
| 319 | +echo "" |
| 320 | +echo "=== 检查 API 结果 ===" |
| 321 | +curl -s "http://localhost:8585/api/v1/databaseSchemas/name/postgres-test-03-multiple-users.finance_db.accounting" \ |
| 322 | + -H "Authorization: Bearer $JWT_TOKEN" | jq '.owners | length' |
| 323 | +``` |
| 324 | + |
| 325 | +期望输出: `2` |
| 326 | + |
| 327 | +--- |
| 328 | + |
| 329 | +## 🆘 如果还是不行 |
| 330 | + |
| 331 | +请提供以下信息: |
| 332 | + |
| 333 | +1. **代码检查结果**: |
| 334 | +```bash |
| 335 | +grep -n "database_owner_names" ingestion/src/metadata/ingestion/source/database/common_db_source.py |
| 336 | +``` |
| 337 | + |
| 338 | +2. **日志片段**: |
| 339 | +```bash |
| 340 | +grep -C 3 "inherited" /tmp/ingestion_debug.log |
| 341 | +``` |
| 342 | + |
| 343 | +3. **API 返回**: |
| 344 | +```bash |
| 345 | +curl ... | jq '.owners' |
| 346 | +``` |
| 347 | + |
| 348 | +我会根据这些信息进一步诊断! |
0 commit comments