I have been using Slingshot! for writing to a SQL database for years, but with a new project in Revit 2025 and Dynamo 3.3 I can not get the Command.ODBC_Command node to work. No error message on the node, just a failure to write to the SQL database. I tested Slingshot! in Revit 2024 Dynamo 2.19 and it still works. I have DynamoIronPython2 package installed as well.
Thanks !
This one is C# based so the Python engine isn’t going to be the issue.
Most likely the issue is a Dynamo, .NET, SQL, or other dependency update which is at fault. This package is something like 12 years old at this point if my initial research is correct - a VERY impressive run of stability. If in fact it was a .NET update then this may become a consistent issue - Dynamo and Revit updated from .NET 4 to .NET 8 in 2025. Microsoft’s .NET policy is a 2 year support cycle - so new breaking changes may be intruded every other year going forward (Revit 2027 and Dynamo 4.0 are written for .NET 10).
The fix will likely require an update to the Slingshot code base, putting this out of reach for all but the package author. Best to reach out to them directly.
Thanks Jacob, I agree it was a good run for that package. I’m looking into replacing this with Python, wish me luck
C# will be far easier and more efficient if you’re pulling to go that route - It’s a .NET library after all. ![]()
It does look like slingshot was open-sourced before it was effectively discontinued:
Well, I spoke to Copilot all day today and it made me a Python script to write my data from a Revit schedule to my SQL database. I could study Python for 10 years and never be able to write this!
import clr
clr.AddReference("System.Data")
from System.Data.SqlClient import SqlConnection, SqlCommand
from System import DBNull
# Inputs
data = IN[0]
conn_string = IN[1]
columns = [
"scheduleId",
"printerId",
"templateId",
"schedName",
"jobNo",
"jobName",
"date",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"h7",
"h8",
"h9",
"h10",
"h11",
"h12",
"f1",
"f2",
"f3",
"f4",
"f5",
"f6",
"f7",
"f8",
"f9",
"f10",
"f11",
"f12"
]
conn = None
trans = None
try:
# Handle Dynamo nesting
rows = data
while (
isinstance(rows, list)
and len(rows) == 1
and isinstance(rows[0], list)
and len(rows[0]) > 0
and isinstance(rows[0][0], list)
):
rows = rows[0]
# Make sure there is data to write
if rows is None or len(rows) == 0:
raise Exception("No rows were provided.")
# Validate first row before using scheduleId
if len(rows[0]) != len(columns):
raise Exception(
"First row has {} columns. Expected {} columns.".format(
len(rows[0]),
len(columns)
)
)
# Get scheduleId from first column of first row
scheduleId = rows[0][0]
if scheduleId is None or str(scheduleId).strip() == "":
raise Exception("scheduleId is blank. Delete/insert operation cancelled.")
scheduleId = str(scheduleId).strip()
# Build INSERT statement
column_sql = ", ".join(["[" + c + "]" for c in columns])
parameter_sql = ", ".join(["@" + c for c in columns])
insert_sql = """
INSERT INTO dbo_schedule
({0})
VALUES
({1})
""".format(column_sql, parameter_sql)
# Open SQL connection
conn = SqlConnection(conn_string)
conn.Open()
# Start transaction
trans = conn.BeginTransaction()
# ------------------------------------------------------------
# DELETE OLD ROWS FIRST
# ------------------------------------------------------------
delete_sql = """
DELETE FROM dbo_schedule
WHERE scheduleId = @scheduleId
"""
delete_cmd = SqlCommand(delete_sql, conn)
delete_cmd.Transaction = trans
delete_cmd.Parameters.AddWithValue("@scheduleId", scheduleId)
deleted = delete_cmd.ExecuteNonQuery()
# ------------------------------------------------------------
# INSERT NEW ROWS
# ------------------------------------------------------------
inserted = 0
for row_index, row in enumerate(rows):
if len(row) != len(columns):
raise Exception(
"Row {} has {} columns. Expected {} columns.".format(
row_index + 1,
len(row),
len(columns)
)
)
cmd = SqlCommand(insert_sql, conn)
cmd.Transaction = trans
for i, col in enumerate(columns):
value = row[i]
# Convert blanks and null text to SQL NULL
if value is None:
value = DBNull.Value
elif str(value).strip() == "":
value = DBNull.Value
elif str(value).lower().strip() == "null":
value = DBNull.Value
cmd.Parameters.AddWithValue("@" + col, value)
cmd.ExecuteNonQuery()
inserted += 1
# Commit delete and insert together
trans.Commit()
conn.Close()
# Multiline success message
message = "\n".join([
"Schedule data replaced successfully.",
"scheduleId: {}".format(scheduleId),
"Rows deleted: {}".format(deleted),
"Rows inserted: {}".format(inserted)
])
OUT = [
True,
message
]
except Exception as ex:
try:
if trans is not None:
trans.Rollback()
except:
pass
try:
if conn is not None:
conn.Close()
except:
pass
# Multiline failure message
message = "\n".join([
"Schedule data write failed.",
"Error:",
str(ex)
])
OUT = [
False,
message
]
And it’s written in VB .NET ![]()
Slingshot was a great package.
It pains me to see many people on this forum struggling to do everything in Excel, when a database (SQL, SQLite) is a far better option
Nathan (the author) is still around but seems to have vanished from the Dynamo scene & is concentrating on Grasshopper.
i would say it depends what it should be used for…
