Skip to content

Conversation

@geoHeil
Copy link
Collaborator

@geoHeil geoHeil commented Nov 21, 2025

a very first rough draft

eventually resolves #159

Copy link
Collaborator Author

geoHeil commented Nov 21, 2025

@geoHeil geoHeil mentioned this pull request Nov 21, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

Coverage

Coverage Report (Python 3.12)
FileStmtsMissCoverMissing
__init__.py17382%79, 83–84
_packaging.py28871%17–18, 40, 43–44, 46, 48, 96
_utils.py19289%26, 32
config.py1932487%49, 55, 60, 73–74, 222–225, 258, 265–266, 268, 271, 428, 453, 461–462, 464–465, 467, 495, 533, 562
entrypoints.py661084%156, 171, 215–216, 218–219, 221–222, 225–226
_testing
   metaxy_project.py2493087%93, 129, 136, 199, 306, 308–314, 353, 418, 439, 474, 488, 520, 533, 586, 719, 732, 734–740, 746
   models.py22195%40
   runbook.py1591689%89, 114, 151, 243, 245, 247–248, 333, 368, 384, 413, 436–437, 444, 463, 533
_testing/parametric
   metadata.py1253175%121–122, 127, 130, 132–133, 135, 138, 144–146, 148, 152–153, 155–156, 161–162, 165–166, 168, 171, 173, 322, 354, 594–596, 601, 610, 638
cli
   context.py502746%44–45, 49–50, 52–54, 66–68, 72, 80–82, 86, 99, 111, 113, 121–122, 124, 128, 156–157, 159, 164, 167
ext/dagster
   resource.py711874%41–44, 48–50, 54–55, 59, 63–64, 68, 72–73, 77, 139, 183
ext/sqlalchemy
   plugin.py64198%148
ext/sqlmodel
   plugin.py60985%93–95, 148–149, 151–152, 154, 156
graph
   describe.py1361304%46–47, 53, 56, 61–62, 64–65, 67, 69–71, 73–75, 77–80, 82, 85–88, 91, 96–98, 100–111, 114–117, 120, 130–132, 134, 159–161, 164–167, 169, 173, 175, 180–181, 183–184, 186–187, 189, 191–193, 195–197, 199–201, 206, 208, 214–215, 218, 220–225, 227–228, 230, 256–263, 265, 269, 271, 276–277, 279–280, 282–283, 285, 288–294, 299–300, 302–303, 309–310, 313, 315–320, 322–323, 325
   utils.py11190%17
graph/diff
   diff_models.py1431688%70, 82, 154, 171, 182, 200, 214, 228, 242, 299, 319, 333, 357, 378, 399, 420
   differ.py2782391%42, 74, 127–128, 133, 152, 173–174, 179, 192, 194–196, 198, 454, 573, 607, 705, 709–710, 740–741, 755
   models.py1648647%110, 121, 152, 182, 186, 209, 227, 274, 276–277, 280–282, 285, 288–290, 292–293, 295, 301, 304–306, 309, 312, 320, 323–324, 326, 342, 344–345, 348, 350, 353–361, 363, 366–367, 370–373, 376–377, 379–380, 382, 385–398, 400–402, 405–407, 409, 415, 418, 424, 432, 435–438, 440
   traversal.py968511%24, 41–42, 44–45, 47–50, 52, 55, 59–61, 63, 66–67, 69, 83–85, 87–89, 91–92, 94–95, 97–98, 100–102, 105–108, 110, 133–135, 138, 141–144, 147–150, 153, 157, 164, 183, 185–187, 189, 191–194, 196–197, 199–200, 215–221, 223, 225–227, 229–231, 233–234, 236–237, 245
graph/diff/rendering
   base.py935639%99–100, 103–104, 106, 111, 123, 135, 172–173, 176–177, 180–181, 183–185, 196–198, 209–216, 218, 232–234, 250, 261, 269, 272–274, 276–277, 280–281, 285–286, 289–295, 298, 306–307, 309, 315
   cards.py89827%23–25, 27, 30, 33, 35–36, 38–40, 43–46, 50, 53–61, 66–68, 71, 78–80, 91–92, 94, 97–98, 101, 104–106, 108, 111–112, 114–116, 118–120, 122–124, 127–131, 133, 144, 147–148, 153–155, 157–158, 160–161, 164–166, 168, 179–186, 188
   formatter.py2945182%62, 64, 66, 82–87, 89, 104, 125–127, 130, 134, 137, 139, 144, 149, 155, 160–163, 165–166, 171, 174–175, 180, 183–184, 189, 194, 198, 210, 222–223, 438–439, 444–445, 454, 461, 465, 555–556, 597–598, 730
   graphviz.py1141048%24, 27, 30–32, 35–36, 38–43, 46, 48–51, 54–55, 57, 61, 64–69, 71, 74–76, 78–79, 81–83, 86, 88, 94, 98, 100, 112–113, 116–119, 121, 132–139, 141, 152–159, 161, 172, 175–177, 179–180, 182–184, 186–187, 189–190, 192, 203, 206–208, 210–211, 216–218, 220–221, 223–224, 226, 237–244, 246
   mermaid.py13712310%25, 28, 31, 33–35, 37–38, 41, 44, 46–48, 51–59, 62, 64, 71, 74, 77–79, 82–84, 87, 92–94, 96, 99–100, 102, 113, 125–128, 130, 141, 155, 158, 160, 163–165, 167, 169, 171, 174, 176, 179, 181, 184, 186, 191–192, 194, 205, 208–209, 212–213, 218–220, 223–224, 226–227, 229–231, 233–234, 236–237, 239, 242, 244–247, 250–251, 262, 265–267, 269–270, 272–273, 278–280, 282–283, 285–286, 288, 290, 301–306, 308, 319–324, 326
   rich.py72659%23–24, 26, 29, 32–34, 38, 41, 43–45, 48–50, 60, 63, 68–69, 72–73, 75, 78, 81–82, 84–85, 88–90, 92–93, 96–99, 102–106, 118, 120, 125–126, 131, 134, 137–138, 140–141, 144–146, 148–149, 160–167, 169
   theme.py16193%48
metadata_store
   _ducklake_support.py2253484%41, 43, 46, 55, 62, 75, 81, 89, 96–97, 110–111, 129, 132, 140, 150, 178–180, 182, 207, 261, 269, 271, 279, 285, 288, 377, 405–408, 411, 414
   base.py3663690%273, 318, 341, 442, 473–474, 517, 519, 659, 676, 681, 890, 989, 1047, 1054, 1062, 1068, 1168, 1362, 1382–1383, 1387, 1392, 1399, 1404–1405, 1410, 1417, 1419, 1428, 1430, 1433, 1436, 1458–1459, 1462
   bigquery.py661183%201, 227–228, 266, 271, 276, 281, 286, 292, 297, 302
   clickhouse.py41978%78, 113, 118, 123, 128, 136, 141, 146, 151
   delta.py1081685%77, 93, 96, 130–131, 190, 234, 258, 261–262, 265, 273, 313, 319–321
   duckdb.py1502980%52–58, 60, 171–172, 176, 244, 254–256, 258, 266–267, 288, 293, 298, 312–313, 324, 329, 387, 394, 400, 405
   ibis.py1221091%158, 177, 328–329, 331, 356, 370, 388, 444, 471
   memory.py871385%79, 82, 84–85, 88, 122, 124, 132, 134, 158, 161–162, 203
   warnings.py22195%29
metadata_store/system
   models.py44393%92–93, 108
   storage.py1644373%143, 189, 379, 381–383, 385–386, 389–390, 392–396, 401, 403, 406, 422, 425, 429–430, 436, 438, 445, 465–466, 468, 471, 473–474, 477, 479–480, 483, 486, 497, 505, 518, 730, 816, 827, 832
migrations
   detector.py57984%69, 79, 94–95, 100, 102, 117, 123, 129
   executor.py1512583%54, 59–60, 62, 111–112, 117, 178–180, 194–195, 250–251, 260–261, 293–295, 406, 409–410, 413–414, 422
   generator.py1241240%3–4, 6, 8–13, 20, 33, 35–36, 39–41, 44–46, 48, 51, 106, 108, 110, 112–113, 117, 120–122, 124, 128–129, 134, 137, 140–145, 149, 157, 159–160, 166–167, 170–173, 182, 185, 190–191, 194, 197–199, 201–202, 205, 208, 216–218, 221–224, 226, 228–230, 233–235, 238–241, 244–245, 248, 250–251, 255–257, 260–261, 268–269, 271–273, 275–276, 279–280, 282–283, 285–286, 289–290, 292, 297, 299, 302, 304, 310, 312–314, 316, 319–321, 323, 328, 332, 334, 343
   loader.py927815%26, 28, 30–31, 33–34, 37–40, 42, 58–59, 61–62, 68–73, 75, 78–84, 86, 101–102, 104–105, 107–108, 126, 129, 134–135, 141, 144, 146, 148, 153–154, 161, 178, 180–181, 183–184, 187–190, 192–193, 196–198, 201–202, 204–207, 209–210, 215–218, 221, 224–226, 231
   models.py106892%129, 238, 288, 321–322, 324–326
   ops.py1004159%54–58, 210–211, 223–224, 236, 246, 252–253, 257–258, 261–262, 268, 270, 273–274, 276, 278–279, 282, 292, 296, 299, 304–306, 309, 312–313, 315, 319–320, 325–327, 329
models
   feature.py3955586%72–73, 127, 132, 136, 138–139, 146, 171, 176, 221, 230, 309, 318, 348, 394, 405, 408–410, 412, 540, 642, 753–754, 757–760, 772, 776, 791, 793–794, 797–801, 804, 806, 829, 884, 991–992, 996, 999, 1025–1027, 1270, 1277–1278, 1280, 1286
   feature_spec.py86297%113, 138
   field.py53688%41, 43, 56–57, 59, 163
   fields_mapping.py881088%55, 100–101, 194, 267–270, 273, 275
   filter_expression.py1624075%45, 75, 79–81, 84, 99, 117, 172, 180–184, 187–189, 210, 220–225, 233, 242, 251–255, 270–274, 282–283, 285, 289
   lineage.py44197%74
   plan.py981782%37, 41, 45, 75, 77–78, 80, 84, 86–88, 90, 135, 168, 188, 222–223
   types.py1411490%89–93, 103–104, 106, 131, 167, 181, 187, 193, 199
utils
   exceptions.py6183%10
   hashing.py55689%45, 139, 185, 191, 197, 207
versioning
   engine.py1831094%45, 66, 69, 83, 289, 515, 518, 608, 613, 650
   ibis.py581475%72, 160–161, 164, 167, 170, 173, 178–179, 183–184, 189, 192, 227
   polars.py43295%58, 177
   types.py22195%41
TOTAL6586167274% 

Tests Skipped Failures Errors Time
1069 22 💤 0 ❌ 0 🔥 4m 29s ⏱️

@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

Coverage

Coverage Report (Python 3.11)
FileStmtsMissCoverMissing
__init__.py17382%79, 83–84
_packaging.py28871%17–18, 40, 43–44, 46, 48, 96
_utils.py19289%26, 32
config.py1932487%49, 55, 60, 73–74, 222–225, 258, 265–266, 268, 271, 428, 453, 461–462, 464–465, 467, 495, 533, 562
entrypoints.py661084%156, 171, 215–216, 218–219, 221–222, 225–226
_testing
   metaxy_project.py2493087%93, 129, 136, 199, 306, 308–314, 353, 418, 439, 474, 488, 520, 533, 586, 719, 732, 734–740, 746
   models.py22195%40
   runbook.py1591689%89, 114, 151, 243, 245, 247–248, 333, 368, 384, 413, 436–437, 444, 463, 533
_testing/parametric
   metadata.py1253175%121–122, 127, 130, 132–133, 135, 138, 144–146, 148, 152–153, 155–156, 161–162, 165–166, 168, 171, 173, 322, 354, 594–596, 601, 610, 638
cli
   context.py502746%44–45, 49–50, 52–54, 66–68, 72, 80–82, 86, 99, 111, 113, 121–122, 124, 128, 156–157, 159, 164, 167
ext/dagster
   resource.py711874%41–44, 48–50, 54–55, 59, 63–64, 68, 72–73, 77, 139, 183
ext/sqlalchemy
   plugin.py64198%148
ext/sqlmodel
   plugin.py60985%93–95, 148–149, 151–152, 154, 156
graph
   describe.py1361304%46–47, 53, 56, 61–62, 64–65, 67, 69–71, 73–75, 77–80, 82, 85–88, 91, 96–98, 100–111, 114–117, 120, 130–132, 134, 159–161, 164–167, 169, 173, 175, 180–181, 183–184, 186–187, 189, 191–193, 195–197, 199–201, 206, 208, 214–215, 218, 220–225, 227–228, 230, 256–263, 265, 269, 271, 276–277, 279–280, 282–283, 285, 288–294, 299–300, 302–303, 309–310, 313, 315–320, 322–323, 325
   utils.py11190%17
graph/diff
   diff_models.py1431688%70, 82, 154, 171, 182, 200, 214, 228, 242, 299, 319, 333, 357, 378, 399, 420
   differ.py2782391%42, 74, 127–128, 133, 152, 173–174, 179, 192, 194–196, 198, 454, 573, 607, 705, 709–710, 740–741, 755
   models.py1648647%110, 121, 152, 182, 186, 209, 227, 274, 276–277, 280–282, 285, 288–290, 292–293, 295, 301, 304–306, 309, 312, 320, 323–324, 326, 342, 344–345, 348, 350, 353–361, 363, 366–367, 370–373, 376–377, 379–380, 382, 385–398, 400–402, 405–407, 409, 415, 418, 424, 432, 435–438, 440
   traversal.py968511%24, 41–42, 44–45, 47–50, 52, 55, 59–61, 63, 66–67, 69, 83–85, 87–89, 91–92, 94–95, 97–98, 100–102, 105–108, 110, 133–135, 138, 141–144, 147–150, 153, 157, 164, 183, 185–187, 189, 191–194, 196–197, 199–200, 215–221, 223, 225–227, 229–231, 233–234, 236–237, 245
graph/diff/rendering
   base.py935639%99–100, 103–104, 106, 111, 123, 135, 172–173, 176–177, 180–181, 183–185, 196–198, 209–216, 218, 232–234, 250, 261, 269, 272–274, 276–277, 280–281, 285–286, 289–295, 298, 306–307, 309, 315
   cards.py89827%23–25, 27, 30, 33, 35–36, 38–40, 43–46, 50, 53–61, 66–68, 71, 78–80, 91–92, 94, 97–98, 101, 104–106, 108, 111–112, 114–116, 118–120, 122–124, 127–131, 133, 144, 147–148, 153–155, 157–158, 160–161, 164–166, 168, 179–186, 188
   formatter.py2945182%62, 64, 66, 82–87, 89, 104, 125–127, 130, 134, 137, 139, 144, 149, 155, 160–163, 165–166, 171, 174–175, 180, 183–184, 189, 194, 198, 210, 222–223, 438–439, 444–445, 454, 461, 465, 555–556, 597–598, 730
   graphviz.py1141048%24, 27, 30–32, 35–36, 38–43, 46, 48–51, 54–55, 57, 61, 64–69, 71, 74–76, 78–79, 81–83, 86, 88, 94, 98, 100, 112–113, 116–119, 121, 132–139, 141, 152–159, 161, 172, 175–177, 179–180, 182–184, 186–187, 189–190, 192, 203, 206–208, 210–211, 216–218, 220–221, 223–224, 226, 237–244, 246
   mermaid.py13712310%25, 28, 31, 33–35, 37–38, 41, 44, 46–48, 51–59, 62, 64, 71, 74, 77–79, 82–84, 87, 92–94, 96, 99–100, 102, 113, 125–128, 130, 141, 155, 158, 160, 163–165, 167, 169, 171, 174, 176, 179, 181, 184, 186, 191–192, 194, 205, 208–209, 212–213, 218–220, 223–224, 226–227, 229–231, 233–234, 236–237, 239, 242, 244–247, 250–251, 262, 265–267, 269–270, 272–273, 278–280, 282–283, 285–286, 288, 290, 301–306, 308, 319–324, 326
   rich.py72659%23–24, 26, 29, 32–34, 38, 41, 43–45, 48–50, 60, 63, 68–69, 72–73, 75, 78, 81–82, 84–85, 88–90, 92–93, 96–99, 102–106, 118, 120, 125–126, 131, 134, 137–138, 140–141, 144–146, 148–149, 160–167, 169
   theme.py16193%48
metadata_store
   _ducklake_support.py2253484%41, 43, 46, 55, 62, 75, 81, 89, 96–97, 110–111, 129, 132, 140, 150, 178–180, 182, 207, 261, 269, 271, 279, 285, 288, 377, 405–408, 411, 414
   base.py3663690%273, 318, 341, 442, 473–474, 517, 519, 659, 676, 681, 890, 989, 1047, 1054, 1062, 1068, 1168, 1362, 1382–1383, 1387, 1392, 1399, 1404–1405, 1410, 1417, 1419, 1428, 1430, 1433, 1436, 1458–1459, 1462
   bigquery.py661183%201, 227–228, 266, 271, 276, 281, 286, 292, 297, 302
   clickhouse.py41978%78, 113, 118, 123, 128, 136, 141, 146, 151
   delta.py1081685%77, 93, 96, 130–131, 190, 234, 258, 261–262, 265, 273, 313, 319–321
   duckdb.py1502980%52–58, 60, 171–172, 176, 244, 254–256, 258, 266–267, 288, 293, 298, 312–313, 324, 329, 387, 394, 400, 405
   ibis.py1221091%158, 177, 328–329, 331, 356, 370, 388, 444, 471
   memory.py871385%79, 82, 84–85, 88, 122, 124, 132, 134, 158, 161–162, 203
   warnings.py22195%29
metadata_store/system
   models.py44393%92–93, 108
   storage.py1644373%143, 189, 379, 381–383, 385–386, 389–390, 392–396, 401, 403, 406, 422, 425, 429–430, 436, 438, 445, 465–466, 468, 471, 473–474, 477, 479–480, 483, 486, 497, 505, 518, 730, 816, 827, 832
migrations
   detector.py57984%69, 79, 94–95, 100, 102, 117, 123, 129
   executor.py1512583%54, 59–60, 62, 111–112, 117, 178–180, 194–195, 250–251, 260–261, 293–295, 406, 409–410, 413–414, 422
   generator.py1241240%3–4, 6, 8–13, 20, 33, 35–36, 39–41, 44–46, 48, 51, 106, 108, 110, 112–113, 117, 120–122, 124, 128–129, 134, 137, 140–145, 149, 157, 159–160, 166–167, 170–173, 182, 185, 190–191, 194, 197–199, 201–202, 205, 208, 216–218, 221–224, 226, 228–230, 233–235, 238–241, 244–245, 248, 250–251, 255–257, 260–261, 268–269, 271–273, 275–276, 279–280, 282–283, 285–286, 289–290, 292, 297, 299, 302, 304, 310, 312–314, 316, 319–321, 323, 328, 332, 334, 343
   loader.py927815%26, 28, 30–31, 33–34, 37–40, 42, 58–59, 61–62, 68–73, 75, 78–84, 86, 101–102, 104–105, 107–108, 126, 129, 134–135, 141, 144, 146, 148, 153–154, 161, 178, 180–181, 183–184, 187–190, 192–193, 196–198, 201–202, 204–207, 209–210, 215–218, 221, 224–226, 231
   models.py106892%129, 238, 288, 321–322, 324–326
   ops.py1004159%54–58, 210–211, 223–224, 236, 246, 252–253, 257–258, 261–262, 268, 270, 273–274, 276, 278–279, 282, 292, 296, 299, 304–306, 309, 312–313, 315, 319–320, 325–327, 329
models
   feature.py3955586%72–73, 127, 132, 136, 138–139, 146, 171, 176, 221, 230, 309, 318, 348, 394, 405, 408–410, 412, 540, 642, 753–754, 757–760, 772, 776, 791, 793–794, 797–801, 804, 806, 829, 884, 991–992, 996, 999, 1025–1027, 1270, 1277–1278, 1280, 1286
   feature_spec.py86297%113, 138
   field.py53688%41, 43, 56–57, 59, 163
   fields_mapping.py881088%55, 100–101, 194, 267–270, 273, 275
   filter_expression.py1624075%45, 75, 79–81, 84, 99, 117, 172, 180–184, 187–189, 210, 220–225, 233, 242, 251–255, 270–274, 282–283, 285, 289
   lineage.py44197%74
   plan.py981782%37, 41, 45, 75, 77–78, 80, 84, 86–88, 90, 135, 168, 188, 222–223
   types.py1411490%89–93, 103–104, 106, 131, 167, 181, 187, 193, 199
utils
   exceptions.py6183%10
   hashing.py55689%45, 139, 185, 191, 197, 207
versioning
   engine.py1831094%45, 66, 69, 83, 289, 515, 518, 608, 613, 650
   ibis.py581475%72, 160–161, 164, 167, 170, 173, 178–179, 183–184, 189, 192, 227
   polars.py43295%58, 177
   types.py22195%41
TOTAL6586167274% 

Tests Skipped Failures Errors Time
1069 22 💤 0 ❌ 0 🔥 3m 47s ⏱️

@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

Coverage

Coverage Report (Python 3.10)
FileStmtsMissCoverMissing
__init__.py17382%79, 83–84
_packaging.py28871%17–18, 40, 43–44, 46, 48, 96
_utils.py19289%26, 32
config.py1932487%49, 55, 60, 73–74, 222–225, 258, 265–266, 268, 271, 428, 453, 461–462, 464–465, 467, 495, 533, 562
entrypoints.py661084%156, 171, 215–216, 218–219, 221–222, 225–226
_testing
   metaxy_project.py2493087%93, 129, 136, 199, 306, 308–314, 353, 418, 439, 474, 488, 520, 533, 586, 719, 732, 734–740, 746
   models.py22195%40
   runbook.py1591689%89, 114, 151, 243, 245, 247–248, 333, 368, 384, 413, 436–437, 444, 463, 533
_testing/parametric
   metadata.py1253175%121–122, 127, 130, 132–133, 135, 138, 144–146, 148, 152–153, 155–156, 161–162, 165–166, 168, 171, 173, 322, 354, 594–596, 601, 610, 638
cli
   context.py502746%44–45, 49–50, 52–54, 66–68, 72, 80–82, 86, 99, 111, 113, 121–122, 124, 128, 156–157, 159, 164, 167
ext/dagster
   resource.py711874%41–44, 48–50, 54–55, 59, 63–64, 68, 72–73, 77, 139, 183
ext/sqlalchemy
   plugin.py64198%148
ext/sqlmodel
   plugin.py60985%93–95, 148–149, 151–152, 154, 156
graph
   describe.py1361304%46–47, 53, 56, 61–62, 64–65, 67, 69–71, 73–75, 77–80, 82, 85–88, 91, 96–98, 100–111, 114–117, 120, 130–132, 134, 159–161, 164–167, 169, 173, 175, 180–181, 183–184, 186–187, 189, 191–193, 195–197, 199–201, 206, 208, 214–215, 218, 220–225, 227–228, 230, 256–263, 265, 269, 271, 276–277, 279–280, 282–283, 285, 288–294, 299–300, 302–303, 309–310, 313, 315–320, 322–323, 325
   utils.py11190%17
graph/diff
   diff_models.py1431688%70, 82, 154, 171, 182, 200, 214, 228, 242, 299, 319, 333, 357, 378, 399, 420
   differ.py2782391%42, 74, 127–128, 133, 152, 173–174, 179, 192, 194–196, 198, 454, 573, 607, 705, 709–710, 740–741, 755
   models.py1648647%110, 121, 152, 182, 186, 209, 227, 274, 276–277, 280–282, 285, 288–290, 292–293, 295, 301, 304–306, 309, 312, 320, 323–324, 326, 342, 344–345, 348, 350, 353–361, 363, 366–367, 370–373, 376–377, 379–380, 382, 385–398, 400–402, 405–407, 409, 415, 418, 424, 432, 435–438, 440
   traversal.py968511%24, 41–42, 44–45, 47–50, 52, 55, 59–61, 63, 66–67, 69, 83–85, 87–89, 91–92, 94–95, 97–98, 100–102, 105–108, 110, 133–135, 138, 141–144, 147–150, 153, 157, 164, 183, 185–187, 189, 191–194, 196–197, 199–200, 215–221, 223, 225–227, 229–231, 233–234, 236–237, 245
graph/diff/rendering
   base.py935639%99–100, 103–104, 106, 111, 123, 135, 172–173, 176–177, 180–181, 183–185, 196–198, 209–216, 218, 232–234, 250, 261, 269, 272–274, 276–277, 280–281, 285–286, 289–295, 298, 306–307, 309, 315
   cards.py89827%23–25, 27, 30, 33, 35–36, 38–40, 43–46, 50, 53–61, 66–68, 71, 78–80, 91–92, 94, 97–98, 101, 104–106, 108, 111–112, 114–116, 118–120, 122–124, 127–131, 133, 144, 147–148, 153–155, 157–158, 160–161, 164–166, 168, 179–186, 188
   formatter.py2945182%62, 64, 66, 82–87, 89, 104, 125–127, 130, 134, 137, 139, 144, 149, 155, 160–163, 165–166, 171, 174–175, 180, 183–184, 189, 194, 198, 210, 222–223, 438–439, 444–445, 454, 461, 465, 555–556, 597–598, 730
   graphviz.py1141048%24, 27, 30–32, 35–36, 38–43, 46, 48–51, 54–55, 57, 61, 64–69, 71, 74–76, 78–79, 81–83, 86, 88, 94, 98, 100, 112–113, 116–119, 121, 132–139, 141, 152–159, 161, 172, 175–177, 179–180, 182–184, 186–187, 189–190, 192, 203, 206–208, 210–211, 216–218, 220–221, 223–224, 226, 237–244, 246
   mermaid.py13712310%25, 28, 31, 33–35, 37–38, 41, 44, 46–48, 51–59, 62, 64, 71, 74, 77–79, 82–84, 87, 92–94, 96, 99–100, 102, 113, 125–128, 130, 141, 155, 158, 160, 163–165, 167, 169, 171, 174, 176, 179, 181, 184, 186, 191–192, 194, 205, 208–209, 212–213, 218–220, 223–224, 226–227, 229–231, 233–234, 236–237, 239, 242, 244–247, 250–251, 262, 265–267, 269–270, 272–273, 278–280, 282–283, 285–286, 288, 290, 301–306, 308, 319–324, 326
   rich.py72659%23–24, 26, 29, 32–34, 38, 41, 43–45, 48–50, 60, 63, 68–69, 72–73, 75, 78, 81–82, 84–85, 88–90, 92–93, 96–99, 102–106, 118, 120, 125–126, 131, 134, 137–138, 140–141, 144–146, 148–149, 160–167, 169
   theme.py16193%48
metadata_store
   _ducklake_support.py2253484%41, 43, 46, 55, 62, 75, 81, 89, 96–97, 110–111, 129, 132, 140, 150, 178–180, 182, 207, 261, 269, 271, 279, 285, 288, 377, 405–408, 411, 414
   base.py3663690%273, 318, 341, 442, 473–474, 517, 519, 659, 676, 681, 890, 989, 1047, 1054, 1062, 1068, 1168, 1362, 1382–1383, 1387, 1392, 1399, 1404–1405, 1410, 1417, 1419, 1428, 1430, 1433, 1436, 1458–1459, 1462
   bigquery.py661183%201, 227–228, 266, 271, 276, 281, 286, 292, 297, 302
   clickhouse.py41978%78, 113, 118, 123, 128, 136, 141, 146, 151
   delta.py1081685%77, 93, 96, 130–131, 190, 234, 258, 261–262, 265, 273, 313, 319–321
   duckdb.py1502980%52–58, 60, 171–172, 176, 244, 254–256, 258, 266–267, 288, 293, 298, 312–313, 324, 329, 387, 394, 400, 405
   ibis.py1221091%158, 177, 328–329, 331, 356, 370, 388, 444, 471
   memory.py871385%79, 82, 84–85, 88, 122, 124, 132, 134, 158, 161–162, 203
   warnings.py22195%29
metadata_store/system
   models.py44393%92–93, 108
   storage.py1644373%143, 189, 379, 381–383, 385–386, 389–390, 392–396, 401, 403, 406, 422, 425, 429–430, 436, 438, 445, 465–466, 468, 471, 473–474, 477, 479–480, 483, 486, 497, 505, 518, 730, 816, 827, 832
migrations
   detector.py57984%69, 79, 94–95, 100, 102, 117, 123, 129
   executor.py1512583%54, 59–60, 62, 111–112, 117, 178–180, 194–195, 250–251, 260–261, 293–295, 406, 409–410, 413–414, 422
   generator.py1241240%3–4, 6, 8–13, 20, 33, 35–36, 39–41, 44–46, 48, 51, 106, 108, 110, 112–113, 117, 120–122, 124, 128–129, 134, 137, 140–145, 149, 157, 159–160, 166–167, 170–173, 182, 185, 190–191, 194, 197–199, 201–202, 205, 208, 216–218, 221–224, 226, 228–230, 233–235, 238–241, 244–245, 248, 250–251, 255–257, 260–261, 268–269, 271–273, 275–276, 279–280, 282–283, 285–286, 289–290, 292, 297, 299, 302, 304, 310, 312–314, 316, 319–321, 323, 328, 332, 334, 343
   loader.py927815%26, 28, 30–31, 33–34, 37–40, 42, 58–59, 61–62, 68–73, 75, 78–84, 86, 101–102, 104–105, 107–108, 126, 129, 134–135, 141, 144, 146, 148, 153–154, 161, 178, 180–181, 183–184, 187–190, 192–193, 196–198, 201–202, 204–207, 209–210, 215–218, 221, 224–226, 231
   models.py106892%129, 238, 288, 321–322, 324–326
   ops.py1004159%54–58, 210–211, 223–224, 236, 246, 252–253, 257–258, 261–262, 268, 270, 273–274, 276, 278–279, 282, 292, 296, 299, 304–306, 309, 312–313, 315, 319–320, 325–327, 329
models
   feature.py3955586%72–73, 127, 132, 136, 138–139, 146, 171, 176, 221, 230, 309, 318, 348, 394, 405, 408–410, 412, 540, 642, 753–754, 757–760, 772, 776, 791, 793–794, 797–801, 804, 806, 829, 884, 991–992, 996, 999, 1025–1027, 1270, 1277–1278, 1280, 1286
   feature_spec.py86297%113, 138
   field.py53688%41, 43, 56–57, 59, 163
   fields_mapping.py881088%55, 100–101, 194, 267–270, 273, 275
   filter_expression.py1624075%45, 75, 79–81, 84, 99, 117, 172, 180–184, 187–189, 210, 220–225, 233, 242, 251–255, 270–274, 282–283, 285, 289
   lineage.py44197%74
   plan.py981782%37, 41, 45, 75, 77–78, 80, 84, 86–88, 90, 135, 168, 188, 222–223
   types.py1411490%89–93, 103–104, 106, 131, 167, 181, 187, 193, 199
utils
   exceptions.py6183%10
   hashing.py55689%45, 139, 185, 191, 197, 207
versioning
   engine.py1831094%45, 66, 69, 83, 289, 515, 518, 608, 613, 650
   ibis.py581475%72, 160–161, 164, 167, 170, 173, 178–179, 183–184, 189, 192, 227
   polars.py43295%58, 177
   types.py22195%41
TOTAL6586167274% 

Tests Skipped Failures Errors Time
1069 22 💤 0 ❌ 0 🔥 3m 51s ⏱️

@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2025

Coverage

Coverage Report (Python 3.13)
FileStmtsMissCoverMissing
__init__.py17382%79, 83–84
_packaging.py28871%17–18, 40, 43–44, 46, 48, 96
_utils.py19289%26, 32
config.py1932487%49, 55, 60, 73–74, 222–225, 258, 265–266, 268, 271, 428, 453, 461–462, 464–465, 467, 495, 533, 562
entrypoints.py661084%156, 171, 215–216, 218–219, 221–222, 225–226
_testing
   metaxy_project.py2493087%93, 129, 136, 199, 306, 308–314, 353, 418, 439, 474, 488, 520, 533, 586, 719, 732, 734–740, 746
   models.py22195%40
   runbook.py1591689%89, 114, 151, 243, 245, 247–248, 333, 368, 384, 413, 436–437, 444, 463, 533
_testing/parametric
   metadata.py1253175%121–122, 127, 130, 132–133, 135, 138, 144–146, 148, 152–153, 155–156, 161–162, 165–166, 168, 171, 173, 322, 354, 594–596, 601, 610, 638
cli
   context.py502746%44–45, 49–50, 52–54, 66–68, 72, 80–82, 86, 99, 111, 113, 121–122, 124, 128, 156–157, 159, 164, 167
ext/dagster
   resource.py711874%41–44, 48–50, 54–55, 59, 63–64, 68, 72–73, 77, 139, 183
ext/sqlalchemy
   plugin.py64198%148
ext/sqlmodel
   plugin.py60985%93–95, 148–149, 151–152, 154, 156
graph
   describe.py1361304%46–47, 53, 56, 61–62, 64–65, 67, 69–71, 73–75, 77–80, 82, 85–88, 91, 96–98, 100–111, 114–117, 120, 130–132, 134, 159–161, 164–167, 169, 173, 175, 180–181, 183–184, 186–187, 189, 191–193, 195–197, 199–201, 206, 208, 214–215, 218, 220–225, 227–228, 230, 256–263, 265, 269, 271, 276–277, 279–280, 282–283, 285, 288–294, 299–300, 302–303, 309–310, 313, 315–320, 322–323, 325
   utils.py11190%17
graph/diff
   diff_models.py1431688%70, 82, 154, 171, 182, 200, 214, 228, 242, 299, 319, 333, 357, 378, 399, 420
   differ.py2782391%42, 74, 127–128, 133, 152, 173–174, 179, 192, 194–196, 198, 454, 573, 607, 705, 709–710, 740–741, 755
   models.py1648647%110, 121, 152, 182, 186, 209, 227, 274, 276–277, 280–282, 285, 288–290, 292–293, 295, 301, 304–306, 309, 312, 320, 323–324, 326, 342, 344–345, 348, 350, 353–361, 363, 366–367, 370–373, 376–377, 379–380, 382, 385–398, 400–402, 405–407, 409, 415, 418, 424, 432, 435–438, 440
   traversal.py968511%24, 41–42, 44–45, 47–50, 52, 55, 59–61, 63, 66–67, 69, 83–85, 87–89, 91–92, 94–95, 97–98, 100–102, 105–108, 110, 133–135, 138, 141–144, 147–150, 153, 157, 164, 183, 185–187, 189, 191–194, 196–197, 199–200, 215–221, 223, 225–227, 229–231, 233–234, 236–237, 245
graph/diff/rendering
   base.py935639%99–100, 103–104, 106, 111, 123, 135, 172–173, 176–177, 180–181, 183–185, 196–198, 209–216, 218, 232–234, 250, 261, 269, 272–274, 276–277, 280–281, 285–286, 289–295, 298, 306–307, 309, 315
   cards.py89827%23–25, 27, 30, 33, 35–36, 38–40, 43–46, 50, 53–61, 66–68, 71, 78–80, 91–92, 94, 97–98, 101, 104–106, 108, 111–112, 114–116, 118–120, 122–124, 127–131, 133, 144, 147–148, 153–155, 157–158, 160–161, 164–166, 168, 179–186, 188
   formatter.py2945182%62, 64, 66, 82–87, 89, 104, 125–127, 130, 134, 137, 139, 144, 149, 155, 160–163, 165–166, 171, 174–175, 180, 183–184, 189, 194, 198, 210, 222–223, 438–439, 444–445, 454, 461, 465, 555–556, 597–598, 730
   graphviz.py1141048%24, 27, 30–32, 35–36, 38–43, 46, 48–51, 54–55, 57, 61, 64–69, 71, 74–76, 78–79, 81–83, 86, 88, 94, 98, 100, 112–113, 116–119, 121, 132–139, 141, 152–159, 161, 172, 175–177, 179–180, 182–184, 186–187, 189–190, 192, 203, 206–208, 210–211, 216–218, 220–221, 223–224, 226, 237–244, 246
   mermaid.py13712310%25, 28, 31, 33–35, 37–38, 41, 44, 46–48, 51–59, 62, 64, 71, 74, 77–79, 82–84, 87, 92–94, 96, 99–100, 102, 113, 125–128, 130, 141, 155, 158, 160, 163–165, 167, 169, 171, 174, 176, 179, 181, 184, 186, 191–192, 194, 205, 208–209, 212–213, 218–220, 223–224, 226–227, 229–231, 233–234, 236–237, 239, 242, 244–247, 250–251, 262, 265–267, 269–270, 272–273, 278–280, 282–283, 285–286, 288, 290, 301–306, 308, 319–324, 326
   rich.py72659%23–24, 26, 29, 32–34, 38, 41, 43–45, 48–50, 60, 63, 68–69, 72–73, 75, 78, 81–82, 84–85, 88–90, 92–93, 96–99, 102–106, 118, 120, 125–126, 131, 134, 137–138, 140–141, 144–146, 148–149, 160–167, 169
   theme.py16193%48
metadata_store
   _ducklake_support.py2253484%41, 43, 46, 55, 62, 75, 81, 89, 96–97, 110–111, 129, 132, 140, 150, 178–180, 182, 207, 261, 269, 271, 279, 285, 288, 377, 405–408, 411, 414
   base.py3663690%273, 318, 341, 442, 473–474, 517, 519, 659, 676, 681, 890, 989, 1047, 1054, 1062, 1068, 1168, 1362, 1382–1383, 1387, 1392, 1399, 1404–1405, 1410, 1417, 1419, 1428, 1430, 1433, 1436, 1458–1459, 1462
   bigquery.py661183%201, 227–228, 266, 271, 276, 281, 286, 292, 297, 302
   clickhouse.py41978%78, 113, 118, 123, 128, 136, 141, 146, 151
   delta.py1081685%77, 93, 96, 130–131, 190, 234, 258, 261–262, 265, 273, 313, 319–321
   duckdb.py1502980%52–58, 60, 171–172, 176, 244, 254–256, 258, 266–267, 288, 293, 298, 312–313, 324, 329, 387, 394, 400, 405
   ibis.py1221091%158, 177, 328–329, 331, 356, 370, 388, 444, 471
   memory.py871385%79, 82, 84–85, 88, 122, 124, 132, 134, 158, 161–162, 203
   warnings.py22195%29
metadata_store/system
   models.py44393%92–93, 108
   storage.py1644373%143, 189, 379, 381–383, 385–386, 389–390, 392–396, 401, 403, 406, 422, 425, 429–430, 436, 438, 445, 465–466, 468, 471, 473–474, 477, 479–480, 483, 486, 497, 505, 518, 730, 816, 827, 832
migrations
   detector.py57984%69, 79, 94–95, 100, 102, 117, 123, 129
   executor.py1512583%54, 59–60, 62, 111–112, 117, 178–180, 194–195, 250–251, 260–261, 293–295, 406, 409–410, 413–414, 422
   generator.py1241240%3–4, 6, 8–13, 20, 33, 35–36, 39–41, 44–46, 48, 51, 106, 108, 110, 112–113, 117, 120–122, 124, 128–129, 134, 137, 140–145, 149, 157, 159–160, 166–167, 170–173, 182, 185, 190–191, 194, 197–199, 201–202, 205, 208, 216–218, 221–224, 226, 228–230, 233–235, 238–241, 244–245, 248, 250–251, 255–257, 260–261, 268–269, 271–273, 275–276, 279–280, 282–283, 285–286, 289–290, 292, 297, 299, 302, 304, 310, 312–314, 316, 319–321, 323, 328, 332, 334, 343
   loader.py927815%26, 28, 30–31, 33–34, 37–40, 42, 58–59, 61–62, 68–73, 75, 78–84, 86, 101–102, 104–105, 107–108, 126, 129, 134–135, 141, 144, 146, 148, 153–154, 161, 178, 180–181, 183–184, 187–190, 192–193, 196–198, 201–202, 204–207, 209–210, 215–218, 221, 224–226, 231
   models.py106892%129, 238, 288, 321–322, 324–326
   ops.py1004159%54–58, 210–211, 223–224, 236, 246, 252–253, 257–258, 261–262, 268, 270, 273–274, 276, 278–279, 282, 292, 296, 299, 304–306, 309, 312–313, 315, 319–320, 325–327, 329
models
   feature.py3955586%72–73, 127, 132, 136, 138–139, 146, 171, 176, 221, 230, 309, 318, 348, 394, 405, 408–410, 412, 540, 642, 753–754, 757–760, 772, 776, 791, 793–794, 797–801, 804, 806, 829, 884, 991–992, 996, 999, 1025–1027, 1270, 1277–1278, 1280, 1286
   feature_spec.py86297%113, 138
   field.py53688%41, 43, 56–57, 59, 163
   fields_mapping.py881088%55, 100–101, 194, 267–270, 273, 275
   filter_expression.py1624075%45, 75, 79–81, 84, 99, 117, 172, 180–184, 187–189, 210, 220–225, 233, 242, 251–255, 270–274, 282–283, 285, 289
   lineage.py44197%74
   plan.py981782%37, 41, 45, 75, 77–78, 80, 84, 86–88, 90, 135, 168, 188, 222–223
   types.py1411490%89–93, 103–104, 106, 131, 167, 181, 187, 193, 199
utils
   exceptions.py6183%10
   hashing.py55689%45, 139, 185, 191, 197, 207
versioning
   engine.py1831094%45, 66, 69, 83, 289, 515, 518, 608, 613, 650
   ibis.py581475%72, 160–161, 164, 167, 170, 173, 178–179, 183–184, 189, 192, 227
   polars.py43295%58, 177
   types.py22195%41
TOTAL6586167274% 

Tests Skipped Failures Errors Time
1069 22 💤 0 ❌ 0 🔥 3m 55s ⏱️

@geoHeil geoHeil force-pushed the 11-21-metaxymetadatastoreresource branch 4 times, most recently from ad2dbe3 to e4e9d77 Compare November 22, 2025 13:52
@geoHeil geoHeil self-assigned this Nov 22, 2025
@geoHeil geoHeil force-pushed the 11-21-metaxymetadatastoreresource branch 2 times, most recently from d723165 to 57e2f2c Compare November 22, 2025 22:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces Dagster integration for Metaxy by implementing a MetaxyMetadataStoreResource that wraps Metaxy metadata stores as Dagster resources. The implementation includes:

  • A configurable resource class that supports fallback stores, config file loading, and auto-discovery
  • Context manager support for resource lifecycle management
  • Comprehensive validation for fallback store compatibility (hash algorithms and truncation lengths)

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

File Description
src/metaxy/ext/dagster/resource.py Core implementation of MetaxyMetadataStoreResource with config loading, fallback store resolution, and validation
src/metaxy/ext/dagster/__init__.py Module exports for the Dagster extension
tests/ext/test_dagster.py Comprehensive test suite covering config loading, fallback store validation, and Dagster integration
pyproject.toml Added dagster dependency to optional extras and dev dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"""Context manager exit - closes the underlying store."""
if hasattr(self, "_active_store") and self._active_store is not None:
self._active_store.__exit__(*args)
self._active_store = None # type: ignore[assignment]
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting _active_store to None conflicts with the type system since _active_store is expected to be a MetadataStore. Consider using del self._active_store instead to properly clean up the attribute, or define _active_store: MetadataStore | None as an explicit attribute on the class.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +42
if not hasattr(self, "_active_store") or self._active_store is None:
self._active_store = self.get_store()
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _active_store attribute is never declared on the class, which makes the code harder to understand and may cause issues with type checkers. Consider declaring it as a class attribute: _active_store: MetadataStore | None = None.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +34
if TYPE_CHECKING:
pass
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty if TYPE_CHECKING: block serves no purpose. Remove this conditional or add the necessary type imports inside it.

Suggested change
if TYPE_CHECKING:
pass

Copilot uses AI. Check for mistakes.
@geoHeil geoHeil closed this Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[integrations/dagster] make a MetaxyMetadataStoreResource

3 participants