Only show guides for your app
Take the connection string from the Databases page and turn it into working queries — in Node, Python, and beyond.
You made a database — now let's make your code talk to it. The pattern is the same in every language: store the connection string as an environment variable, read it at startup, hand it to a database driver. Do that once and the queries are just ordinary SQL.
| At a glance | |
|---|---|
| You need | A managed database of any type (Add a database) and an app server running your language |
| Plan | Any |
| Time | About twenty minutes |
⚠️ Heads up: Never hard-code the connection string.
Copy it from the Databases page and store it as DATABASE_URL in your server's .env file — see Environment variables and secrets for how .env works on Falix. Your code reads it from the environment: process.env.DATABASE_URL in Node, os.environ["DATABASE_URL"] in Python. If you ever rotate the password, you paste the new string into .env and nothing else changes.
A driver is the library that speaks the database's wire protocol. Add it the easy way: open the Packages page in your server menu, type the package name into the Install package panel, press Install, then restart the server so your app loads it. For MySQL that's mysql2 (Node) or PyMySQL (Python).
With mysql2 installed, index.js:
const mysql = require('mysql2/promise');
async function main() {
const db = await mysql.createConnection(process.env.DATABASE_URL);
await db.execute(`
CREATE TABLE IF NOT EXISTS scores (
user_id VARCHAR(32) PRIMARY KEY,
points INT NOT NULL DEFAULT 0
)
`);
await db.execute(
`INSERT INTO scores (user_id, points) VALUES (?, ?)
ON DUPLICATE KEY UPDATE points = points + VALUES(points)`,
['alice', 5]
);
const [rows] = await db.execute('SELECT * FROM scores');
console.log(rows);
await db.end();
}
main().catch(console.error);
createConnection takes the whole URL, so there's nothing to parse. CREATE TABLE IF NOT EXISTS makes the table on first run and does nothing afterward. The ON DUPLICATE KEY UPDATE line is an upsert — insert a row, or add to it if that user_id already exists — exactly the shape a bot's scoreboard needs.
PyMySQL doesn't take a URL directly, so split it apart with urlparse. app.py:
import os
from urllib.parse import urlparse
import pymysql
url = urlparse(os.environ["DATABASE_URL"])
conn = pymysql.connect(
host=url.hostname,
port=url.port,
user=url.username,
password=url.password,
database=url.path.lstrip("/"),
)
with conn.cursor() as cur:
cur.execute(
"CREATE TABLE IF NOT EXISTS scores ("
" user_id VARCHAR(32) PRIMARY KEY,"
" points INT NOT NULL DEFAULT 0)"
)
cur.execute(
"INSERT INTO scores (user_id, points) VALUES (%s, %s)"
" ON DUPLICATE KEY UPDATE points = points + VALUES(points)",
("alice", 5),
)
conn.commit()
cur.execute("SELECT * FROM scores")
print(cur.fetchall(), flush=True)
conn.close()
urlparse pulls the host, port, user, password, and database name out of the same string you copied from the panel. flush=True makes the output show up in the console right away.
💡 Tip: Don't forget
conn.commit()— without it your inserts roll back when the connection closes.
🎯 Good to know: Nothing above changes except the string and the library.
Use the connection string the panel gives you for that database type, keep it in DATABASE_URL, and reach for the standard driver:
PostgreSQL: pg in Node, psycopg in Python. Both accept the postgresql://… string directly — for example in Node:
const { Client } = require('pg');
const db = new Client({ connectionString: process.env.DATABASE_URL });
await db.connect();
MongoDB: the mongodb driver in Node (or pymongo in Python). It takes the whole mongodb://…?authSource=… string as-is:
const { MongoClient } = require('mongodb');
const client = new MongoClient(process.env.DATABASE_URL);
await client.connect();
From there the queries are whatever that driver documents — the Falix-specific part is done once you're connected. Install any of these from the Packages page just like mysql2.
The examples above open one connection, do their work, and close it — exactly right for a script that runs a task and exits. A bot or web server is different: it stays up for hours, and a single connection left open can quietly drop (an idle timeout, a network blip). After that, every query throws until something reconnects.
The fix is a connection pool — a small set of connections the driver keeps ready, handing one out per query and replacing any that die. In most drivers it's a small change:
mysql2): swap createConnection for createPool, then call pool.execute(...) per query — same API, and no manual end().pg): use new Pool(...) in place of new Client(...).PyMySQL): it has no built-in pool — keep one connection open for the app's life and reconnect if a query fails, or let a layer like SQLAlchemy pool for you.mongodb / pymongo): the client already pools internally — create one client when the app starts and reuse it everywhere; never open one per request.Open the pool (or client) once at startup, reuse it for the whole run, and let it manage the connections for you.
Start the server and watch the Console. The Node example prints the rows it just wrote; the Python one prints the fetched tuples. See your inserted row and the round trip works — code to database and back. For MySQL you can also open phpMyAdmin from the Databases page and see the scores table sitting there.
.env.localhost). Copy the host value from the database exactly as shown.