r/learnpython • • 2d ago

How to fix error : sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file ?

i was trying to run this jupyter notebook ( https://github.com/langchain-ai/lca-lc-foundations/blob/main/notebooks/module-2/2.4_wedding_planners.ipynb ) code in my IDE but encountered these problems :
my code :
https://pastebin.com/3bv05GfE
error :
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file

also i dont know how to work with async functions so i have defined two function main() and main_1 but am not sure if this is the correct way to go with async functions

0 Upvotes

8 comments sorted by

2

u/Ecstatic-Warthog5727 1d ago

There are two separate problems in that paste.

1. The database path. sqlite:///resources/Chinook.db is relative to the directory you run Python from, not to your script. In the course repo the file lives at notebooks/module-2/resources/Chinook.db, and the notebook works because Jupyter starts inside notebooks/module-2. When you run from your IDE the working directory is probably your project root, there's no resources/ folder there, and SQLite says "unable to open database file" (it won't create missing folders). Build the path from the script's location instead:

from pathlib import Path

DB_PATH = Path(__file__).resolve().parent / "resources" / "Chinook.db"
db = SQLDatabase.from_uri(f"sqlite:///{DB_PATH}")

and copy the resources folder from the repo next to your script.

2. The async part. A notebook lets you write await at the top level, so the course does tools = await client.get_tools() and uses tools further down. A script can't, which is why you wrapped it in main(). But now tools only exists inside main(), so create_agent(..., tools=tools) for the travel agent will fail with a NameError as soon as the database error is fixed. Put everything that needs tools in one async function and call asyncio.run once at the bottom:

async def main():
    client = MultiServerMCPClient({...})
    tools = await client.get_tools()

    travel_agent = create_agent(model="gpt-5-nano", tools=tools, system_prompt="...")
    # the other agents, the @tool functions that call them, and the coordinator go here too

    response = await coordinator.ainvoke({...}, config={...})
    print(response["messages"][-1].content)

asyncio.run(main())

The @tool functions like search_flights use travel_agent, so define them inside main() after the agents (or make the agents module-level variables that main() fills in). Then delete main_1() and the first asyncio.run(main()).

1

u/TreacleFlaky2283 1d ago

Thanks a lot for this

1

u/weeb_jp 2d ago

Yeah, SQLite being unable to open the DB is usually a path/working-directory issue. "os.getcwd()" is the first thing I'd check.

1

u/momiji_tools 1d ago

Your pastebin passes "sqlite:///resources/Chinook.db" into SQLDatabase.from_uri. The three-slash sqlite:/// form makes the path relative to the process current working directory, not to your .py file. Jupyter worked because its cwd contained resources/, but running from an IDE sets the cwd to your home or project root, so resources/Chinook.db resolves in the wrong place and raises "unable to open database file". Make the DB path absolute from the script location:

from pathlib import Path
DB_DIR = Path(__file__).resolve().parent / "resources"
DB_PATH = DB_DIR / "Chinook.db"

and build the URI as "sqlite:///" + str(DB_PATH). Before connecting, confirm Path(DB_PATH).parent.exists() is True and the file is inside the repo's resources/ folder; SQLite will not create intermediate directories. A quick print(os.getcwd()) right before the connection usually shows exactly where resources/ is being looked up.

-1

u/sporbywg 1d ago

To fix this, switch to Typescript

2

u/MasterpieceBusy7220 1d ago

Tiny brain commenter