Converting an existing project to use dg
This feature is considered in a preview stage and is under active development. It can change significantly, or be removed completely. It is not considered ready for production use.
This guide is only relevant if you are starting from an existing Dagster project. This setup is unnecessary if you scaffolded a new project with dg scaffold project
.
We have a basic existing Dagster project and have been using pip
to manage
our Python environment. Our project defines a Python package with a setup.py
and a single Dagster asset. The asset is exposed in a top-level Definitions
object in my_existing_project/definitions.py
.
tree
.
├── README.md
├── my_existing_project
│ ├── __init__.py
│ ├── assets.py
│ └── definitions.py
└── setup.py
2 directories, 5 files
Install dependencies
Install the dg
command line tool
Let's start with a fresh Python virtual environment (you may already have one):
python -m venv .venv && source .venv/bin/activate
We'll need to install the dg
command line tool. You can install it into the
virtual environment using pip
:
pip install dagster-dg
For simplicity in this tutorial, we are installing the dg
executable into the
same virtual environment as our project. However, we generally recommend
installing dg
globally using the
uv
package manager
via uv tool install dagster-dg
. This will install dagster-dg
into an
isolated environment and make it a globally available executable. This makes it
easier to work with multiple projects using dg
.
Install dagster-components
Next, we'll need to add dagster-components
as a dependency of our project. Add it to install_requires
in setup.py
:
from setuptools import find_packages, setup
with open("README.md", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="my_existing_project",
version="0.1.0",
description="Add your description here",
long_description=long_description,
long_description_content_type="text/markdown",
python_requires=">=3.9,<3.13",
packages=find_packages(),
install_requires=[
"dagster",
"dagster-components",
],
extras_require={
"dev": [
"dagster-webserver",
"pytest>8",
]
},
)
Now we install (or reinstall) our project into the active virtual environment:
pip install -e .
Update project structure
Add pyproject.toml
The dg
command recognizes Dagster projects through the presence of a
pyproject.toml
file with a tool.dg
section. If you are already using
pyproject.toml
for your project, you can just add the requisite tool.dg
to the file. Since our sample project has a setup.py
and no pyproject.toml
,
we need to create a new pyproject.toml
file. This can co-exist with
setup.py
-- it is purely a source of config for dg
. Here is the config we
need to put in pyproject.toml
:
[tool.dg]
directory_type = "project"
[tool.dg.project]
root_module = "my_existing_project"
code_location_target_module = "my_existing_project.definitions"
There are three settings:
tool.dg.directory_type = "project"
: This is howdg
identifies your package as a Dagster project. This is required.tool.dg.project.root_module = "my_existing_project"
: This points to the root module of your project. This is also required.tool.dg.project.code_location_target_module = "my_existing_project.definitions"
: This tellsdg
where to find the top-levelDefinitions
object in your project. This actually defaults to[root_module].definitions
, so it is not strictly necessary for us to set it here, but we are including this setting in order to be explicit--existing projects might have the top-levelDefinitions
object defined in a different module, in which case this setting is required. Now that these settings are in place, you can interact with your project usingdg
. If we rundg list defs
we can see the sole existing asset in our project:
dg list defs
Assets
┏━━━━━━━━━━┳━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┓
┃ Key ┃ Group ┃ Deps ┃ Kinds ┃ Description ┃
┡━━━━━━━━━━╇━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━━━━━━ ━┩
│ my_asset │ default │ │ │ │
└──────────┴─────────┴──────┴───────┴─────────────┘
Create a defs
directory
Part of the dg
experience is autoloading definitions. This means
automatically picking up any definitions that exist in a particular module. We
are going to create a new submodule named my_existing_project.defs
(defs
is
the conventional name of the module for where definitions live in dg
) from which we will autoload definitions.
mkdir my_existing_project/defs
Modify top-level definitions
Autoloading is provided by a function from dagster-components
that returns a Definitions
object. Because we already have some other definitions in our project, we'll combine those with the autoloaded ones from my_existing_project.defs
.
To do so, you'll need to modify your definitions.py
file, or whichever file contains your top-level Definitions
object.
You'll autoload definitions using load_defs
, then merge them with your existing definitions using Definitions.merge
. You pass load_defs
the defs
module you just created:
- Before
- After
import dagster as dg
from my_existing_project.assets import my_asset
defs = dg.Definitions(
assets=[my_asset],
)
import dagster_components as dg_components
import my_existing_project.defs
from my_existing_project.assets import my_asset
import dagster as dg
defs = dg.Definitions.merge(
dg.Definitions(assets=[my_asset]),
dg_components.load_defs(my_existing_project.defs),
)
Now let's add an asset to the new defs
module. Create
my_existing_project/defs/autoloaded_asset.py
with the following contents:
import dagster as dg
@dg.asset
def autoloaded_asset(): ...
Finally, let's confirm the new asset is being autoloaded. Run dg list defs
again and you should see both the new autoloaded_asset
and old my_asset
:
dg list defs
Assets
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┓
┃ Key ┃ Group ┃ Deps ┃ Kinds ┃ Description ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━┩
│ autoloaded_asset │ default │ │ │ │
│ my_asset │ default │ │ │ │
└──────────────────┴─────────┴──────┴───────┴─────────────┘
Now your project is fully compatible with dg
!