This file contains the ORM versions of the graph node in types.py.
Pydantic allows us to extract out a Dataclass like object from the ORM,
but not let us directly write to the ORM.
Relationships
Warning
non exhaustive list
SessionContext
- ImportNode (One to Many)
- HardwareSpec (Many to One)
Node
- SessionContext (Many to One)
CallNode
- Node (Many to Many)
ArtifactORM
Bases: Base
An artifact is a named pointer to a node.
Source code in lineapy/db/relational.py
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 | class ArtifactORM(Base):
"""
An artifact is a named pointer to a node.
"""
__tablename__ = "artifact"
id = Column(Integer, primary_key=True, autoincrement=True)
node_id: LineaID = Column(String, ForeignKey("node.id"), nullable=False)
execution_id: LineaID = Column(
String, ForeignKey("execution.id"), nullable=False
)
name = Column(
String,
nullable=False,
default=ARTIFACT_NAME_PLACEHOLDER,
)
date_created = Column(DateTime, nullable=False)
version = Column(Integer, nullable=False)
node: BaseNodeORM = relationship(
"BaseNodeORM", uselist=False, lazy="joined", innerjoin=True
)
execution: ExecutionORM = relationship(
"ExecutionORM", uselist=False, lazy="joined", innerjoin=True
)
__table_args__ = (
UniqueConstraint(
"name", "version", name="_unique_artifact_name_and_version"
),
UniqueConstraint(
"name",
"node_id",
"execution_id",
"version",
name="_unique_artifact_name_for_a_node_id_and_exec_id",
),
)
|
BaseNodeORM
Bases: Base
node.source_code has a path value if node.session.environment_type == "script"
otherwise the environment type is "jupyter" and it has a jupyter execution
count and session id, which is equal to the node.session
Note
Because other nodes are inheriting from BaseNodeORM, finding a node
based on its id is easy (something like the following)::
session.query(BaseNodeORM).filter(BaseNodeORM.id == linea_id)
Each node inheriting from BaseNodeORM must have non null values for
all of lineno, col_offset, end_lineno, end_col_offset and source_code_id
or nulls for all of them.
Source code in lineapy/db/relational.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248 | class BaseNodeORM(Base):
"""
node.source_code has a path value if node.session.environment_type == "script"
otherwise the environment type is "jupyter" and it has a jupyter execution
count and session id, which is equal to the node.session
??? note
Because other nodes are inheriting from BaseNodeORM, finding a node
based on its id is easy (something like the following)::
session.query(BaseNodeORM).filter(BaseNodeORM.id == linea_id)
Each node inheriting from BaseNodeORM must have non null values for
all of lineno, col_offset, end_lineno, end_col_offset and source_code_id
or nulls for all of them.
"""
__tablename__ = "node"
id = Column(String, primary_key=True)
session_id: LineaID = Column(String)
node_type = Column(Enum(NodeType))
lineno = Column(Integer, nullable=True) # line numbers are 1-indexed
col_offset = Column(Integer, nullable=True) # col numbers are 0-indexed
end_lineno = Column(Integer, nullable=True)
end_col_offset = Column(Integer, nullable=True)
control_dependency = Column(String, ForeignKey("node.id"), nullable=True)
source_code_id = Column(
String, ForeignKey("source_code.id"), nullable=True
)
source_code: SourceCodeORM = relationship("SourceCodeORM", lazy="joined")
__table_args__ = (
# Either all source keys or none should be specified
CheckConstraint(
"(lineno IS NULL) = (col_offset is NULL) and "
"(col_offset is NULL) = (end_lineno is NULL) and "
"(end_lineno is NULL) = (end_col_offset is NULL) and "
"(end_col_offset is NULL) = (source_code_id is NULL)"
),
)
# https://docs.sqlalchemy.org/en/14/orm/inheritance.html#joined-table-inheritance
__mapper_args__ = {
"polymorphic_on": node_type,
"polymorphic_identity": NodeType.Node,
}
|
ExecutionORM
Bases: Base
An execution represents one Python interpreter invocation of some number of nodes
Source code in lineapy/db/relational.py
173
174
175
176
177
178
179
180 | class ExecutionORM(Base):
"""
An execution represents one Python interpreter invocation of some number of nodes
"""
__tablename__ = "execution"
id = Column(String, primary_key=True)
timestamp = Column(DateTime, nullable=True, default=datetime.utcnow)
|
NodeValueORM
Bases: Base
A node value represents the value of a node during some execution.
It is uniquely identified by the node_id
and execution_id
.
The following invariant holds:
value.node.session == value.execution.session
Source code in lineapy/db/relational.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 | class NodeValueORM(Base):
"""
A node value represents the value of a node during some execution.
It is uniquely identified by the `node_id` and `execution_id`.
The following invariant holds:
`value.node.session == value.execution.session`
"""
__tablename__ = "node_value"
node_id = Column(String, ForeignKey("node.id"), primary_key=True)
execution_id = Column(String, ForeignKey("execution.id"), primary_key=True)
value = Column(String, nullable=True)
value_type = Column(Enum(ValueType))
start_time = Column(DateTime, nullable=True)
end_time = Column(DateTime, nullable=True)
|