How to get primary key name on laravel query builder
Asked Answered
A

6

7

Is there a way to get a table's primary key name using the Laravel query builder? Can i do something like

$key = DB::table($someTable)->getPrimaryKey();

I've looked through the documentation and API but couldn't find any reference to it.

Thanks in advance.

Aesop answered 16/4, 2018 at 16:5 Comment(0)
M
6

You can get an array of indexes for a table directly using the Schema manager:

$indexes = DB::connection()->getDoctrineSchemaManager()->listTableIndexes($table);

OR

$indexes = Schema::getConnection()->getDoctrineSchemaManager()->listTableIndexes($table);

And then you can get an array of the columns associated with that index key:

$columns = $indexes[ 'primary' ]->getColumns();

This function can be used to find the primary key(s) or unique key(s) for a table you know nothing about:

public function getTablePrimaryOrUniqueKey($table, $key='') {
    //get the array of table indexes
    $indexes = DB::connection()->getDoctrineSchemaManager()->listTableIndexes($table);

    //abort if there are no indexes
    if(!is_array($indexes)) return false;

    //set up the default array of index keys
    $keys = ['primary', 'unique'];

    //if a key was passed and it is valid, use it...but cast as an array
    if($key!='' && in_array($key, $keys)) $keys = (array) $key;

    //loop through the keys array
    foreach ( $keys as $key ) {
        //keep it honest
        if ( array_key_exists( $key, $indexes ) ) {
            //get the columns for this key
            $columns = $indexes[ $key ]->getColumns();

            //if we have an array of columns, we have what we need
            if ( is_array( $columns ) ) {
                return $columns;
            }
        }
    }

    //if you got here, you did not get find what you were looking for
    return false;
}
Moreen answered 15/9, 2019 at 20:0 Comment(0)
R
4

my approach is :

$result = DB::select(DB::raw("SHOW KEYS FROM {$table} WHERE Key_name = 'PRIMARY'"));
$primaryKey = $result[0]->Column_name;  

and i use mysql

Righteous answered 20/12, 2018 at 17:34 Comment(1)
This was the right approach for me. Worked like a dream!Clavichord
G
3

The Illuminate/Database/Eloquent/Model class has a getKeyName function which is public.

Inside your model class, you can access the primary key using $this->getKeyName().

Greenburg answered 16/4, 2018 at 16:7 Comment(3)
I'm not using an Eloquent model. I want to do it through the query builder.Pettigrew
In this case I think you'll need to use some SQL. Laravel seems not to have this out of the box.Greenburg
The question was based on the query builder, note any database model!Tinea
P
1

You can use ->getKey() on a model:

$someModel->getKey();

Or if you're just trying to get the name of the column, without having an instance of the model:

app(App\Model::class)->getKeyName()

Proverbial answered 16/4, 2018 at 16:8 Comment(5)
getKey actually returns the value of the primary keyGreenburg
Are you trying to get the name of the column? Use ->getKeyName()Proverbial
I'm not using an Eloquent model. I want to do it through the query builder.Pettigrew
That's not possible. You could make a SQL query to get it maybe.Proverbial
Thanks for this. I wanted the key itself, and this question is one of the top results on Google. 🙏Fourpenny
C
0
$primary_key = app($builder->getModel())->getKeyName();

if you referenced the model when you initialized that Query Builder instance you can retrieve the model reference then use it to get the keyName. but if your just directly called a new Query Builder there isn't a way to see the primary key without doing a select against the table keys, maybe in a subselect?

SHOW KEYS FROM table WHERE Key_name = 'PRIMARY'
Carpous answered 8/10, 2018 at 17:35 Comment(0)
C
0

This is what i put in my UP migration.

I based my answer off of AXE's answer. So give him the upvotes. Basically I took his answer and modified it to use collection tools for simpler syntax.

Basically ran a query SHOW KEYS, get the results, collected them, and used contains to see if the PK exists, and removed the PK that was not supposed to be there.

$result = collect(DB::select(DB::raw("SHOW KEYS FROM `example_table` WHERE Key_name = 'PRIMARY'")));
if ($result->map->Column_name->contains('user_id')) {
    DB::unprepared("ALTER TABLE `example_table` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`)");
}
Clavichord answered 21/9, 2023 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.