How to set default postgresql schema for laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Set Default PostgreSQL Schema for Laravel: A Deep Dive
As a senior developer, I often encounter scenarios where the separation between database structure (PostgreSQL schemas) and application code (Laravel Eloquent) creates friction. The issue you've described—where setting up custom roles and schemas in PostgreSQL doesn't automatically translate into Laravel defaulting to that schema—is common. It highlights the crucial difference between how the database server is configured and how the application connects.
This post will walk you through the problem, analyze the underlying PostgreSQL mechanism, and provide robust solutions for ensuring your Laravel application correctly interacts with custom schemas like lara.
Understanding the Root of the Problem: PostgreSQL search_path
When a PostgreSQL session connects to the database, it uses a setting called search_path to determine the order in which schemas are searched when you reference an object (like a table). By default, this is often set to "$user", public, or simply public.
In your setup:
- You created user
lara_userand schemalara. - Laravel connects using credentials for
lara_user. - By default, the session starts searching in the
publicschema. Since you haven't explicitly told PostgreSQL to look inlarafirst, it defaults topublic, leading to confusion when Eloquent tries to find tables unless explicitly prefixed.
Solution 1: Enforcing Schema via Database Configuration (The Server Level)
While Laravel manages the connection credentials, we need to ensure that the user context is correctly established upon connection or query execution.
The most direct way to influence this behavior at the database level is by setting the search_path for the session. This is typically done within a custom function or, more practically for an application context, ensuring your connection setup respects this path.
If you are using tools like psql directly, you would set it:
SET search_path TO lara, public;
However, for an application layer solution that works reliably regardless of the specific user credentials Laravel uses, relying solely on manual session settings can be fragile.
Solution 2: The Laravel/Eloquent Approach (The Application Layer)
Since we are building an application using a framework like Laravel, the most idiomatic and maintainable solution is to manage schema context within your Eloquent models and migrations, rather than trying to force a global server default on every connection. This aligns perfectly with the principles of clean data architecture that Laravel promotes through its ORM capabilities.
Modifying Model Configuration
Instead of relying on PostgreSQL's session defaults, we should explicitly tell Eloquent which schema to use for all operations related to a specific model. You can achieve this by setting the default schema in your models or within custom query scopes:
// Example in a Laravel Model
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
/**
* The default schema for this model.
*
* @var string
*/
protected $schema = 'lara'; // Explicitly set the desired schema
// ... rest of your model code
}
Handling Database Connection Details
Ensure your config/database.php correctly points to the user and database you created, as this is the foundation of the connection:
// config/database.php snippet
'pgsql' => [
'client' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'postgres'), // The database name
'username' => env('DB_USERNAME', 'lara_user'), // The custom user
'password' => env('DB_PASSWORD', 'mypassword'),
],
By explicitly setting the username in your configuration, you ensure Laravel connects as lara_user. By setting $schema within the model, you instruct Eloquent to prefix all table references (e.g., products) with the specified schema (lara.products), ensuring that application logic remains decoupled from server-side session defaults.
Conclusion
The discrepancy you observed is a classic example of separating infrastructure setup (PostgreSQL roles and schemas) from application logic (Laravel Eloquent). Instead of trying to force a global default on the database server, the best practice in an application context is to use the framework's tools—Eloquent models and query builders—to explicitly define the schema context. This approach keeps your code portable, predictable, and adheres to the principles of clean separation, making your Laravel applications more robust and easier to maintain, much like leveraging the power of Laravel for complex data interactions.