diff --git a/app/__init__.py b/app/__init__.py index 7dd6553..01b75b2 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,4 @@ """Python - FastAPI, Postgres, tsvector""" # Current Version -__version__ = "2.1.8" +__version__ = "2.1.9" diff --git a/app/api/llm/llm.py b/app/api/llm/llm.py index 5f6f3a7..7edf1f9 100644 --- a/app/api/llm/llm.py +++ b/app/api/llm/llm.py @@ -21,7 +21,7 @@ def get_llm_records( if prospect_id is not None: # No pagination for single prospect_id lookup select_query = """ - SELECT id, prompt, completion, duration, time, data, model, prospect_id + SELECT id, prompt, completion, duration, time, data, model, prospect_id, search_vector FROM llm WHERE prospect_id = %s ORDER BY id DESC @@ -38,6 +38,7 @@ def get_llm_records( "data": row[5], "model": row[6], "prospect_id": row[7], + "search_vector": str(row[8]) if row[8] is not None else None, } for row in rows ] @@ -61,7 +62,7 @@ def get_llm_records( count_row = cur.fetchone() total = count_row[0] if count_row and count_row[0] is not None else 0 cur.execute(""" - SELECT id, prompt, completion, duration, time, data, model, prospect_id + SELECT id, prompt, completion, duration, time, data, model, prospect_id, search_vector FROM llm ORDER BY id DESC LIMIT %s OFFSET %s; @@ -76,6 +77,7 @@ def get_llm_records( "data": row[5], "model": row[6], "prospect_id": row[7], + "search_vector": str(row[8]) if row[8] is not None else None, } for row in cur.fetchall() ] @@ -146,13 +148,14 @@ def llm_post(payload: dict) -> dict: data_blob = json.dumps({"version": __version__}) conn = get_db_connection_direct() cur = conn.cursor() + # Generate tsvector from prompt and completion cur.execute( """ - INSERT INTO llm (prompt, completion, duration, data, model, prospect_id) - VALUES (%s, %s, %s, %s, %s, %s) + INSERT INTO llm (prompt, completion, duration, data, model, prospect_id, search_vector) + VALUES (%s, %s, %s, %s, %s, %s, to_tsvector('english', %s || ' ' || %s)) RETURNING id; """, - (prompt, completion, duration, data_blob, used_model, prospect_id) + (prompt, completion, duration, data_blob, used_model, prospect_id, prompt, completion) ) record_id_row = cur.fetchone() record_id = record_id_row[0] if record_id_row else None diff --git a/app/api/llm/sql/alter_add_search_vector.sql b/app/api/llm/sql/alter_add_search_vector.sql new file mode 100644 index 0000000..9e5188f --- /dev/null +++ b/app/api/llm/sql/alter_add_search_vector.sql @@ -0,0 +1,5 @@ +-- Migration: Add search_vector tsvector column to llm table +ALTER TABLE llm ADD COLUMN IF NOT EXISTS search_vector tsvector; + +-- Optional: Create a GIN index for faster search +CREATE INDEX IF NOT EXISTS idx_llm_search_vector ON llm USING GIN(search_vector); \ No newline at end of file diff --git a/app/api/llm/sql/run_alter_add_search_vector.py b/app/api/llm/sql/run_alter_add_search_vector.py new file mode 100644 index 0000000..5a58510 --- /dev/null +++ b/app/api/llm/sql/run_alter_add_search_vector.py @@ -0,0 +1,17 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = """ + ALTER TABLE llm ADD COLUMN IF NOT EXISTS search_vector tsvector; + CREATE INDEX IF NOT EXISTS idx_llm_search_vector ON llm USING GIN(search_vector); + """ + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: search_vector column and index added to llm table.") diff --git a/app/api/prospects/prospects.py b/app/api/prospects/prospects.py index 080e0af..10bb5ad 100644 --- a/app/api/prospects/prospects.py +++ b/app/api/prospects/prospects.py @@ -103,16 +103,15 @@ def prospects_read_one(id: int = Path(..., description="ID of the prospect to re from app.utils.db import get_db_connection_direct llm_conn = get_db_connection_direct() llm_cur = llm_conn.cursor() - llm_cur.execute("SELECT id, prompt, completion, duration, time, data, model FROM llm WHERE prospect_id = %s ORDER BY id DESC;", (id,)) + llm_cur.execute("SELECT id, duration, time, data, model, search_vector FROM llm WHERE prospect_id = %s ORDER BY id DESC;", (id,)) llm_records = [ { "id": r[0], - "prompt": r[1], - "completion": r[2], - "duration": r[3], - "time": r[4].isoformat() if r[4] else None, - "data": r[5], - "model": r[6], + "duration": r[1], + "time": r[2].isoformat() if r[2] else None, + "data": r[3], + "model": r[4], + "search_vector": str(r[5]) if r[5] is not None else None, } for r in llm_cur.fetchall() ] diff --git a/app/api/prospects/sql/alter_drop_cleaned.sql b/app/api/prospects/sql/alter_drop_cleaned.sql new file mode 100644 index 0000000..e3d00d2 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_cleaned.sql @@ -0,0 +1,2 @@ +-- Migration: Remove cleaned column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS cleaned; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_do_not_call.sql b/app/api/prospects/sql/alter_drop_do_not_call.sql new file mode 100644 index 0000000..bd2a310 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_do_not_call.sql @@ -0,0 +1,2 @@ +-- Migration: Remove do_not_call column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS do_not_call; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_email_confidence.sql b/app/api/prospects/sql/alter_drop_email_confidence.sql new file mode 100644 index 0000000..53bacb2 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_email_confidence.sql @@ -0,0 +1,2 @@ +-- Migration: Remove email_confidence column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS email_confidence; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_home_phone.sql b/app/api/prospects/sql/alter_drop_home_phone.sql new file mode 100644 index 0000000..8b6579f --- /dev/null +++ b/app/api/prospects/sql/alter_drop_home_phone.sql @@ -0,0 +1,2 @@ +-- Migration: Remove home_phone column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS home_phone; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_primary_email_catchall_status.sql b/app/api/prospects/sql/alter_drop_primary_email_catchall_status.sql new file mode 100644 index 0000000..7e3035c --- /dev/null +++ b/app/api/prospects/sql/alter_drop_primary_email_catchall_status.sql @@ -0,0 +1,2 @@ +-- Migration: Remove primary_email_catchall_status column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS primary_email_catchall_status; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_primary_intent_score.sql b/app/api/prospects/sql/alter_drop_primary_intent_score.sql new file mode 100644 index 0000000..966bda9 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_primary_intent_score.sql @@ -0,0 +1,2 @@ +-- Migration: Remove primary_intent_score column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS primary_intent_score; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_primary_intent_topic.sql b/app/api/prospects/sql/alter_drop_primary_intent_topic.sql new file mode 100644 index 0000000..e05e48c --- /dev/null +++ b/app/api/prospects/sql/alter_drop_primary_intent_topic.sql @@ -0,0 +1,2 @@ +-- Migration: Remove primary_intent_topic column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS primary_intent_topic; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_qualify_contact.sql b/app/api/prospects/sql/alter_drop_qualify_contact.sql new file mode 100644 index 0000000..d9190c3 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_qualify_contact.sql @@ -0,0 +1,2 @@ +-- Migration: Remove qualify_contact column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS qualify_contact; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_secondary_intent_score.sql b/app/api/prospects/sql/alter_drop_secondary_intent_score.sql new file mode 100644 index 0000000..3ef3184 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_secondary_intent_score.sql @@ -0,0 +1,2 @@ +-- Migration: Remove secondary_intent_score column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS secondary_intent_score; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_secondary_intent_topic.sql b/app/api/prospects/sql/alter_drop_secondary_intent_topic.sql new file mode 100644 index 0000000..df2ff3b --- /dev/null +++ b/app/api/prospects/sql/alter_drop_secondary_intent_topic.sql @@ -0,0 +1,2 @@ +-- Migration: Remove secondary_intent_topic column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS secondary_intent_topic; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_tertiary_email.sql b/app/api/prospects/sql/alter_drop_tertiary_email.sql new file mode 100644 index 0000000..795af9e --- /dev/null +++ b/app/api/prospects/sql/alter_drop_tertiary_email.sql @@ -0,0 +1,2 @@ +-- Migration: Remove tertiary_email column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_tertiary_email_source.sql b/app/api/prospects/sql/alter_drop_tertiary_email_source.sql new file mode 100644 index 0000000..44175cd --- /dev/null +++ b/app/api/prospects/sql/alter_drop_tertiary_email_source.sql @@ -0,0 +1,2 @@ +-- Migration: Remove tertiary_email_source column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_source; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_tertiary_email_status.sql b/app/api/prospects/sql/alter_drop_tertiary_email_status.sql new file mode 100644 index 0000000..2f995f0 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_tertiary_email_status.sql @@ -0,0 +1,2 @@ +-- Migration: Remove tertiary_email_status column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_status; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_tertiary_email_verification_source.sql b/app/api/prospects/sql/alter_drop_tertiary_email_verification_source.sql new file mode 100644 index 0000000..422b329 --- /dev/null +++ b/app/api/prospects/sql/alter_drop_tertiary_email_verification_source.sql @@ -0,0 +1,2 @@ +-- Migration: Remove tertiary_email_verification_source column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_verification_source; \ No newline at end of file diff --git a/app/api/prospects/sql/alter_drop_work_direct_phone.sql b/app/api/prospects/sql/alter_drop_work_direct_phone.sql new file mode 100644 index 0000000..c16ff6e --- /dev/null +++ b/app/api/prospects/sql/alter_drop_work_direct_phone.sql @@ -0,0 +1,2 @@ +-- Migration: Remove work_direct_phone column from prospects table +ALTER TABLE prospects DROP COLUMN IF EXISTS work_direct_phone; \ No newline at end of file diff --git a/app/api/prospects/sql/run_alter_drop_cleaned.py b/app/api/prospects/sql/run_alter_drop_cleaned.py new file mode 100644 index 0000000..a9390c3 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_cleaned.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS cleaned;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: cleaned column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_do_not_call.py b/app/api/prospects/sql/run_alter_drop_do_not_call.py new file mode 100644 index 0000000..3b22e42 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_do_not_call.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS do_not_call;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: do_not_call column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_email_confidence.py b/app/api/prospects/sql/run_alter_drop_email_confidence.py new file mode 100644 index 0000000..2994afc --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_email_confidence.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS email_confidence;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: email_confidence column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_home_phone.py b/app/api/prospects/sql/run_alter_drop_home_phone.py new file mode 100644 index 0000000..9ba423c --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_home_phone.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS home_phone;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: home_phone column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_primary_email_catchall_status.py b/app/api/prospects/sql/run_alter_drop_primary_email_catchall_status.py new file mode 100644 index 0000000..7496194 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_primary_email_catchall_status.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS primary_email_catchall_status;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: primary_email_catchall_status column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_primary_intent_score.py b/app/api/prospects/sql/run_alter_drop_primary_intent_score.py new file mode 100644 index 0000000..38efbd4 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_primary_intent_score.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS primary_intent_score;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: primary_intent_score column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_primary_intent_topic.py b/app/api/prospects/sql/run_alter_drop_primary_intent_topic.py new file mode 100644 index 0000000..eca071d --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_primary_intent_topic.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS primary_intent_topic;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: primary_intent_topic column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_qualify_contact.py b/app/api/prospects/sql/run_alter_drop_qualify_contact.py new file mode 100644 index 0000000..6739b81 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_qualify_contact.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS qualify_contact;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: qualify_contact column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_secondary_intent_score.py b/app/api/prospects/sql/run_alter_drop_secondary_intent_score.py new file mode 100644 index 0000000..3d4bdd8 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_secondary_intent_score.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS secondary_intent_score;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: secondary_intent_score column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_secondary_intent_topic.py b/app/api/prospects/sql/run_alter_drop_secondary_intent_topic.py new file mode 100644 index 0000000..58dddda --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_secondary_intent_topic.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS secondary_intent_topic;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: secondary_intent_topic column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_tertiary_email.py b/app/api/prospects/sql/run_alter_drop_tertiary_email.py new file mode 100644 index 0000000..dfafc67 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_tertiary_email.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: tertiary_email column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_tertiary_email_source.py b/app/api/prospects/sql/run_alter_drop_tertiary_email_source.py new file mode 100644 index 0000000..5a9c361 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_tertiary_email_source.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_source;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: tertiary_email_source column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_tertiary_email_status.py b/app/api/prospects/sql/run_alter_drop_tertiary_email_status.py new file mode 100644 index 0000000..475a867 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_tertiary_email_status.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_status;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: tertiary_email_status column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_tertiary_email_verification_source.py b/app/api/prospects/sql/run_alter_drop_tertiary_email_verification_source.py new file mode 100644 index 0000000..419c7fa --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_tertiary_email_verification_source.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS tertiary_email_verification_source;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: tertiary_email_verification_source column dropped from prospects table.") diff --git a/app/api/prospects/sql/run_alter_drop_work_direct_phone.py b/app/api/prospects/sql/run_alter_drop_work_direct_phone.py new file mode 100644 index 0000000..ce00227 --- /dev/null +++ b/app/api/prospects/sql/run_alter_drop_work_direct_phone.py @@ -0,0 +1,14 @@ +import os +import sys +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../..'))) +from app.utils.db import get_db_connection_direct + +if __name__ == "__main__": + sql = "ALTER TABLE prospects DROP COLUMN IF EXISTS work_direct_phone;" + conn = get_db_connection_direct() + cur = conn.cursor() + cur.execute(sql) + conn.commit() + cur.close() + conn.close() + print("Migration complete: work_direct_phone column dropped from prospects table.")