Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

iamssingh's avatar

Unable to migrate table using point datatype in postgres ?

I have a migration file which contains point datatype. It is laravel 5.8. While migrating I am getting below error.

  Illuminate\Database\QueryException  : SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92 (SQL: create table "clients_users_locations" ("id" bigserial primary key not null, "point_table" geography(geometry, 4326) not null, "created_by" bigint not null, "created_at" timestamp(0) with time zone not null))

  at /opt/lampp/htdocs/project/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668| 

  Exception trace:

  1   Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92")
      /opt/lampp/htdocs/project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:129

  2   PDOException::("SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92")


Here is my migration file -

    public function up()
    {
        Schema::create('clients_users_locations', function (Blueprint $table) {
            $table->bigInteger('id', true);
            $table->geometry('point_table');
            $table->bigInteger('created_by');
            $table->datetimetz('created_at');
        });
    }

What am I missing here ?

0 likes
21 replies
Sinnbeck's avatar

Did you try point instead?

$table->point('point_table');
iamssingh's avatar

@sinnbeck Yeah, It is giving same resopnse.

   Illuminate\Database\QueryException  : SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92 (SQL: create table "clients_users_locations" ("id" bigserial primary key not null, "point_table" geography(point, 4326) not null, "created_by" bigint not null, "created_at" timestamp(0) with time zone not null))

  at /opt/lampp/htdocs/project/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668| 

  Exception trace:

  1   Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92")
      /opt/lampp/htdocs/project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:129

  2   PDOException::("SQLSTATE[42704]: Undefined object: 7 ERROR:  type "geography" does not exist at character 92")
      /opt/lampp/htdocs/project/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:127

Sinnbeck's avatar

So if you copy paste this query to your db manager it works?

create table "clients_users_locations" ("id" bigserial primary key not null, "point_table" geography(point, 4326) not null, "created_by" bigint not null, "created_at" timestamp(0) with time zone not null)
iamssingh's avatar

No, It's not. Using GUI editor, I am able to add point column.

iamssingh's avatar

@sinnbeck When I run SELECT name FROM pg_available_extensions; It shown me all the enabled extension.

Postgis was already there. Still, I created again using CREATE EXTENSION postgis; and migration started working. This migration is creating geography datatype field, not point datatype .

Sinnbeck's avatar

Did you use this?

$table->point('point_table');
iamssingh's avatar

I go through your link - https://postgis.net/install . While hitting below queries.

 	CREATE EXTENSION postgis_raster;
 	CREATE EXTENSION postgis_sfcgal;

I got below errors -

ERROR:  Extension "postgis_raster" is not supported by Amazon RDS
DETAIL:  Installing the extension "postgis_raster" failed, because it is not on the list of extensions supported by Amazon RDS.
HINT:  Amazon RDS allows users with rds_superuser role to install supported extensions. See: SHOW rds.extensions;
SQL state: 22023

ERROR:  Extension "postgis_sfcgal" is not supported by Amazon RDS
DETAIL:  Installing the extension "postgis_raster" failed, because it is not on the list of extensions supported by Amazon RDS.
HINT:  Amazon RDS allows users with rds_superuser role to install supported extensions. See: SHOW rds.extensions;
SQL state: 22023

Are these both(postgis_sfcgal,postgis_raster) are also required for using postgres spatial database datatype ?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Oh seems 5.8 only supports geography :( I think would would need to do a raw migration instead (\DB::statement())

1 like
Sinnbeck's avatar

Yes but as I understand it creates this query

create table "clients_users_locations" ("id" bigserial primary key not null, "point_table" geography(point, 4326) not null, "created_by" bigint not null, "created_at" timestamp(0) with time zone not null)

and you want

create table "clients_users_locations" ("id" bigserial primary key not null, "point_table" geometry(point) not null, "created_by" bigint not null, "created_at" timestamp(0) with time zone not null)

Or am I mistaken ? (Sorry but I have never used postgis before, so I am not sure)

iamssingh's avatar

Okay, Will it be better to upgrade laravel 5.8 to laravel 8.0 ? Is laravel 8.0 stable ?

Sinnbeck's avatar

I assume. But sadly I dont have a setup to test it currently. Perhaps make a test project first? You can try out 7 first. It has the same code as 8 regarding postgres point generation :)

iamssingh's avatar

For anyone, who need the approach to write the perfect code for raw query in this case, I have put my code below. We will be making custom PostgresGrammar class with our overrided method definition. While using it in migration, we simply need to register out Grammer Class here.

Here is the CustomPostgresGrammar -

	<?php
		namespace App\Grammer;

		use Illuminate\Database\Schema\Grammars\PostgresGrammar;
		use Illuminate\Support\Fluent;

		/**
 		* Extended version of PostgresGrammar with
 		* support of 'point' data type in Postgres.
 		*/
		class ExtendedPostgresGrammar extends PostgresGrammar
		{

    		/**
     		* Create the column definition for a spatial Point type.
     		*
     		* @param  \Illuminate\Support\Fluent  $column
     		* @return string
     		*/
    		protected function typePoint(Fluent $column)
    		{
        	return "$column->type";
    		}

	}

Here is the migration file code -

    public function up() {
        // register new grammar class
        DB::connection()->setSchemaGrammar(new ExtendedPostgresGrammar());
        $schema = DB::connection()->getSchemaBuilder();
        $schema->create('locations', function (Blueprint $table) {
            $table->bigInteger('id');
            $table->point('points'); 
            $table->datetimetz('created_at');
         });
     }

2 likes

Please or to participate in this conversation.