Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT]: Support specifying a Postgres Schema other than public #1945

Closed
doctorpangloss opened this issue Apr 25, 2024 · 22 comments
Closed

[FEAT]: Support specifying a Postgres Schema other than public #1945

doctorpangloss opened this issue Apr 25, 2024 · 22 comments

Comments

@doctorpangloss
Copy link

Is your feature request related to a problem? Please describe.
Currently Lago always migrates in the public database schema (namespace).

Describe the solution you'd like
Allow users to specify a schema with a configuration variable. It would be nice if this had defaulted to lago.

@vincent-pochet
Copy link
Collaborator

@doctorpangloss A change have been added to support to the schema. It will be part of the next release
See: getlago/lago#360

Thank you for requesting this change

@alexander-potemkin
Copy link

@vincent-pochet , I'm sorry if that's the wrong channel for that - please, correct me if so.

It seems like I'm having issues with this working - my api container is failing.

I have the following line at my docker-compose.yaml:

- DATABASE_URL=${DATABASE_URL}

And DATABASE_URL defined via .env as follows:

DATABASE_URL="postgresql://MyUserName:MyPassword@MyHost:6543/postgres?search_path=lago"

lago - is a valid scheme, created and accessible (on Supabase's PostgreSQL).

API container logs (docker logs -n 1000 lago-api) shows migration problem:

ESC[1mUnrecognized command "db:migrate:primary" (ESC[1;4mRails::Command::UnrecognizedCommandErrorESC[mESC[1m)ESC[m
ESC[1mDid you mean?  db:migrate:upESC[m
=> Booting Puma
=> Rails 7.1.3.4 application starting in production
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.3.0-p0) ("The Eagle of Durango")
*  Min threads: 0
*  Max threads: 5
*  Environment: production
*          PID: 44
* Listening on http://[::]:3000
Use Ctrl-C to stop
I, [2024-07-03T18:15:07.983771 #44]  INFO -- : [6f2a23b5-ddfe-4239-bd32-9b5040ccc821] {"method":"GET","path":"/health","format":"*/*","controller":"ApplicationController","action":"health","status":200,"allocations":47303,"duration":168.61,"view":0.52,"db":40.04,"ddsource":"ruby","params":{},"organization_id":null}

And indeed if I try to run the migration manually - it's failing - please, find below the logs from within Docker lago-api container:

# docker exec -it lago-api "/bin/sh"
# ps aufx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         124  0.1  0.0   2580   888 pts/0    Ss   18:15   0:00 /bin/sh
root         146  0.0  0.1   8484  4136 pts/0    R+   18:15   0:00  \_ ps aufx
root           1  0.0  0.0   4348  3236 ?        Ss   18:14   0:00 /bin/bash ./scripts/start.sh
root          44 10.6  4.9 1556516 195136 ?      Sl   18:15   0:05 puma 6.4.2 (tcp://[::]:3000) [app]

# bundle exec rails db:migrate:primary
Unrecognized command "db:migrate:primary" (Rails::Command::UnrecognizedCommandError)
Did you mean?  db:migrate:up

My previous Lago installation - on a separate database - worked just fine, so it seems like schema change might be the one to blame... I'm really lost - it doesn't feel like migration could gone missing... 😳

@vincent-pochet
Copy link
Collaborator

@vincent-pochet , I'm sorry if that's the wrong channel for that - please, correct me if so.

It seems like I'm having issues with this working - my api container is failing.

I have the following line at my docker-compose.yaml:

- DATABASE_URL=${DATABASE_URL}

And DATABASE_URL defined via .env as follows:

DATABASE_URL="postgresql://MyUserName:MyPassword@MyHost:6543/postgres?search_path=lago"

lago - is a valid scheme, created and accessible (on Supabase's PostgreSQL).

API container logs (docker logs -n 1000 lago-api) shows migration problem:

ESC[1mUnrecognized command "db:migrate:primary" (ESC[1;4mRails::Command::UnrecognizedCommandErrorESC[mESC[1m)ESC[m
ESC[1mDid you mean?  db:migrate:upESC[m
=> Booting Puma
=> Rails 7.1.3.4 application starting in production
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.3.0-p0) ("The Eagle of Durango")
*  Min threads: 0
*  Max threads: 5
*  Environment: production
*          PID: 44
* Listening on http://[::]:3000
Use Ctrl-C to stop
I, [2024-07-03T18:15:07.983771 #44]  INFO -- : [6f2a23b5-ddfe-4239-bd32-9b5040ccc821] {"method":"GET","path":"/health","format":"*/*","controller":"ApplicationController","action":"health","status":200,"allocations":47303,"duration":168.61,"view":0.52,"db":40.04,"ddsource":"ruby","params":{},"organization_id":null}

And indeed if I try to run the migration manually - it's failing - please, find below the logs from within Docker lago-api container:

# docker exec -it lago-api "/bin/sh"
# ps aufx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         124  0.1  0.0   2580   888 pts/0    Ss   18:15   0:00 /bin/sh
root         146  0.0  0.1   8484  4136 pts/0    R+   18:15   0:00  \_ ps aufx
root           1  0.0  0.0   4348  3236 ?        Ss   18:14   0:00 /bin/bash ./scripts/start.sh
root          44 10.6  4.9 1556516 195136 ?      Sl   18:15   0:05 puma 6.4.2 (tcp://[::]:3000) [app]

# bundle exec rails db:migrate:primary
Unrecognized command "db:migrate:primary" (Rails::Command::UnrecognizedCommandError)
Did you mean?  db:migrate:up

My previous Lago installation - on a separate database - worked just fine, so it seems like schema change might be the one to blame... I'm really lost - it doesn't feel like migration could gone missing... 😳

@alexander-potemkin could you try the following command in the API container

bundle exec rails db:migrate # without the :primary

And restart the application

It does not seems related directly to the change regarding the schema, but to the migrate command in the start.sh script. We will update it and release a fix.

@alexander-potemkin
Copy link

@vincent-pochet , thanks! Now it execute the code, but it seems like ignoring schema nevertheless:

# bundle exec rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied for schema public (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InsufficientPrivilege: ERROR:  permission denied for schema public (PG::InsufficientPrivilege)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

 env | grep -i database
DATABASE_URL=postgresql://MyUser:MyPassword@MyHost:6543/postgres?search_path=lago

@alexander-potemkin
Copy link

alexander-potemkin commented Jul 4, 2024

... and just in case - api worker is not affected, right?

It doesn't seem to be:

$ cat start.worker.sh

#!/bin/bash

bundle exec sidekiq -C config/sidekiq.yml

But I though to ask, just in case.

@vincent-pochet
Copy link
Collaborator

@vincent-pochet , thanks! Now it execute the code, but it seems like ignoring schema nevertheless:

# bundle exec rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied for schema public (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InsufficientPrivilege: ERROR:  permission denied for schema public (PG::InsufficientPrivilege)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

 env | grep -i database
DATABASE_URL=postgresql://MyUser:MyPassword@MyHost:6543/postgres?search_path=lago

@alexander-potemkin 🤔 . In this case the schema_migrations refers to an internal database table. But indeed it looks like the schema part of DATABASE_URL is ignored. I'm having a look

@alexander-potemkin
Copy link

@alexander-potemkin 🤔 . In this case the schema_migrations refers to an internal database table. But indeed it looks like the schema part of DATABASE_URL is ignored. I'm having a look

@vincent-pochet , thank you! Hope it will be all resolved!

Yeah, it does... I tried to check the Lago code yesterday, as it felt like there might be some parts of the code that will just ignore canonical postgresql:// url schema, especially since search_path doesn't seem to be in use so frequently, but I didn't find anything special.
I'm not a Ruby expert though, guess I was looking at the wrong place.

Please, let me know if any additional information would be required!

@vincent-pochet
Copy link
Collaborator

vincent-pochet commented Jul 4, 2024

I found the issue @alexander-potemkin

For some reason, Rails is ignoring the search_path option in the DATABASE_URL, it has to be passed as a config option in the config/database.yml file.

A pull request is open at https://github.com/getlago/lago-api/pull/2246/files with a fix. It will certainly be part of the next release.

To use it and fix your issue, you will have to set the POSTGRES_SCHEMA environment variable

@alexander-potemkin
Copy link

I found the issue @alexander-potemkin

For some reason, Rails is ignoring the search_path option in the DATABASE_URL, it has to be passed as a config option in the config/database.yml file.

A pull request is open at https://github.com/getlago/lago-api/pull/2246/files with a fix. It will certainly be part of the next release.

To use it and fix your issue, you will have to set the POSTGRES_SCHEMA environment variable

Thank you, @vincent-pochet ! It seems, however, something else is missing - please, see the output from within lago-api container below:

# ps aufx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         100  0.0  0.0   2580   892 pts/0    Ss   19:32   0:00 /bin/sh
root         186  0.0  0.1   8488  4124 pts/0    R+   19:33   0:00  \_ ps aufx
root           1  0.0  0.0   4348  3192 ?        Ss   19:31   0:00 /bin/bash ./scripts/start.sh
root          43  6.6  5.1 1574052 204116 ?      Sl   19:31   0:05 puma 6.4.2 (tcp://[::]:3000) [app]
# env | grep POSTGRES_SCHEMA
POSTGRES_SCHEMA=lago
# bundle exec rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied for schema public (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InsufficientPrivilege: ERROR:  permission denied for schema public (PG::InsufficientPrivilege)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

@alexander-potemkin
Copy link

I've applied the config yaml changes from the commit as well manually, inside the container, as it felt appropriate, but it doesn't seem to resolve things:

root@370a0651199e:/app# grep -i schema_search_path config/database.yml
    schema_search_path: "public"
    schema_search_path: <%= ENV.fetch('POSTGRES_SCHEMA', 'public') %>

root@370a0651199e:/app#  bundle exec rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (PG::InvalidSchemaName)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

@alexander-potemkin
Copy link

And just in case - I've hardcoded variables at the config file, but it doesn't seem to help:

root@370a0651199e:/app# bundle exec rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (PG::InvalidSchemaName)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

root@370a0651199e:/app# grep -i schema_search_path config/database.yml
    schema_search_path: lago
    schema_search_path: lago

@alexander-potemkin
Copy link

@vincent-pochet , if the things works on your side - could you possibly share the configuration you have (with private data redacted)? Or I can provide you mine, including full database access if required for the testing?

If something of that could work or there are any other ways to help (including avoid to disturb you) - please, let me know!
I'm also available at the Slack.

vincent-pochet added a commit that referenced this issue Jul 5, 2024
## Context

This PR is a fix for
#1945 (comment)

## Description

Lago startup script is relying on the `rails db:migrate:primary` to
perform the migration at startup.

Since in some situation, only one database is configured in the
`database.yml` file, the command is failing with the following error:
```
Unrecognized command "db:migrate:primary" (Rails::Command::UnrecognizedCommandError)
Did you mean?  db:migrate:up
```

This PR fixes this by using `rails db:migrate` instead when only one
database is present.
@vincent-pochet
Copy link
Collaborator

vincent-pochet commented Jul 5, 2024

@vincent-pochet , if the things works on your side - could you possibly share the configuration you have (with private data redacted)? Or I can provide you mine, including full database access if required for the testing?

If something of that could work or there are any other ways to help (including avoid to disturb you) - please, let me know! I'm also available at the Slack.

Hello @alexander-potemkin

I tried on a local setup. I first created a schema in Postgres and set the its name to the schema_search_path option in the config/database.yml file.
After that I started the container and run the database tasks:

rails db:create
rails db:migrate

After a check in Postgres console, all the table were created.

What version of Lago are you using? Also, just to be sure, did you restarted the app after the update of the database config flle ?

@alexander-potemkin
Copy link

rails db:migrate

Thank you, @vincent-pochet !

Restarted the container, dumped config from there, tried the commands you offered - it failed:

root@370a0651199e:/app# env | grep -i schema
POSTGRES_SCHEMA=lago
root@370a0651199e:/app# rails db:create
PG::InsufficientPrivilege: ERROR:  permission denied to create database
Couldn't create 'postgres' database. Please check your configuration.
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  permission denied to create database (ActiveRecord::StatementInvalid)


Caused by:
PG::InsufficientPrivilege: ERROR:  permission denied to create database (PG::InsufficientPrivilege)

Tasks: TOP => db:create
(See full trace by running task with --trace)
root@370a0651199e:/app# rails db:migrate
bin/rails aborted!
ActiveRecord::StatementInvalid: PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (ActiveRecord::StatementInvalid)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^


Caused by:
PG::InvalidSchemaName: ERROR:  no schema has been selected to create in (PG::InvalidSchemaName)
LINE 1: CREATE TABLE "schema_migrations" ("version" character varyin...
                     ^

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

root@370a0651199e:/app# grep -i schema_search_path config/database.yml
    schema_search_path: "public"
    schema_search_path: <%= ENV.fetch('POSTGRES_SCHEMA', 'public') %>

root@370a0651199e:/app# cat LAGO_VERSION
v1.6.0

Lago version is the latest, from what I can see.

Database can't be created - that's Ok, as it's created already; but migration fails as no schema provided - probably that's the cause?

And just in case - when the changes you applied shall be available? Is there some option for a hotfix release, if that's not too much to ask?

@alexander-potemkin
Copy link

alexander-potemkin commented Jul 5, 2024

I believe that I have found an issue on my side - database permissions were not sufficient - that is to be fixed with the following SQL statements:

GRANT USAGE ON SCHEMA lago TO lago;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA lago TO lago;
GRANT ALL ON ALL SEQUENCES IN SCHEMA lago TO lago;
GRANT ALL ON AL FUNCTIONS IN SCHEMA lago TO lago;
GRANT ALL ON SCHEMA lago TO lago

rails db:migrate executed successfully, but in only created single empty table: last_hour_events_mv.

I tried to register and encountered another error, which is, I believe, somehow related - despite error points to a different direction:

I, [2024-07-05T18:56:12.907098 #35]  INFO -- : [90ab559e-d399-4bbb-8382-3d0494363710] {"method":"POST","path":"/graphql","format":"*/*","controller":"GraphqlController","action":"execute","status":500,"allocations":47789,"duration":375.81,"view":0.0,"db":67.71,"ddsource":"ruby","params":{"operationName":"signup","variables":{"input":{"email":"<...>@<....>","password":"[FILTERED]","organizationName":"<...>"}},"query":"mutation signup($input: RegisterUserInput!) {\n  registerUser(input: $input) {\n    token\n    user {\n      id\n      ...CurrentUser\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment CurrentUser on User {\n  id\n  organizations {\n    id\n    name\n    timezone\n    __typename\n  }\n  __typename\n}"},"organization_id":null}
E, [2024-07-05T18:56:12.908790 #35] ERROR -- : [90ab559e-d399-4bbb-8382-3d0494363710]
[90ab559e-d399-4bbb-8382-3d0494363710] ActiveRecord::StatementInvalid (PG::DuplicatePstatement: ERROR:  prepared statement "a1" already exists
):
[90ab559e-d399-4bbb-8382-3d0494363710]

It feels that something is wrong with the logic maybe - as it feels like db::create has to be executed first - to create database with all tables required (if it works the way I think it should), but db::create fails, as it tries to create database that already exists (and I can't DROP it).

Then db::migrate runs successfully (not a single error), but it seems like fails to create all tables required.

Any clue would be much appreciated!

@alexander-potemkin
Copy link

To make sure things are isolated as much as possible, I created new schema, brought docker cluster down and then up (applying 'patch' on database config) and here is what I have when I try to do migration from scratch:

root@38c541a217ca:/app/scripts# bundle exec rails db:migrate
I, [2024-07-05T19:58:50.010522 #131]  INFO -- : Migrating to InitSchema (20220525122759)
== 20220525122759 InitSchema: migrating =======================================
-- enable_extension("pgcrypto")
   -> 0.0182s
-- create_table("add_ons", {:id=>:uuid, :default=>#<Proc:0x00007f17a0a50d48 /app/db/migrate/20220525122759_init_schema.rb:7 (lambda)>, :force=>:cascade})
   -> 0.0239s
-- create_table("applied_coupons", {:id=>:uuid, :default=>#<Proc:0x00007f17a07f5be8 /app/db/migrate/20220525122759_init_schema.rb:20 (lambda)>, :force=>:cascade})
   -> 0.0436s
-- create_table("billable_metrics", {:id=>:uuid, :default=>#<Proc:0x00007f17a0860420 /app/db/migrate/20220525122759_init_schema.rb:37 (lambda)>, :force=>:cascade})
   -> 0.0289s
-- create_table("charges", {:id=>:uuid, :default=>#<Proc:0x00007f17a089bea8 /app/db/migrate/20220525122759_init_schema.rb:51 (lambda)>, :force=>:cascade})
   -> 0.0316s
-- create_table("coupons", {:id=>:uuid, :default=>#<Proc:0x00007f17a0895710 /app/db/migrate/20220525122759_init_schema.rb:63 (lambda)>, :force=>:cascade})
   -> 0.0357s
-- create_table("credits", {:force=>:cascade})
   -> 0.0272s
-- create_table("customers", {:id=>:uuid, :default=>#<Proc:0x00007f17a02c4ea8 /app/db/migrate/20220525122759_init_schema.rb:93 (lambda)>, :force=>:cascade})
   -> 0.0322s
-- create_table("events", {:id=>:uuid, :default=>#<Proc:0x00007f17a0268798 /app/db/migrate/20220525122759_init_schema.rb:116 (lambda)>, :force=>:cascade})
   -> 0.0432s
-- create_table("fees", {:id=>:uuid, :default=>#<Proc:0x00007f17a0260d40 /app/db/migrate/20220525122759_init_schema.rb:133 (lambda)>, :force=>:cascade})
   -> 0.0366s
-- create_table("invoices", {:id=>:uuid, :default=>#<Proc:0x00007f17a021a048 /app/db/migrate/20220525122759_init_schema.rb:150 (lambda)>, :force=>:cascade})
   -> 0.0374s
-- create_table("memberships", {:id=>:uuid, :default=>#<Proc:0x00007f17a0212528 /app/db/migrate/20220525122759_init_schema.rb:168 (lambda)>, :force=>:cascade})
   -> 0.0274s
-- create_table("organizations", {:id=>:uuid, :default=>#<Proc:0x00007f17a014c558 /app/db/migrate/20220525122759_init_schema.rb:178 (lambda)>, :force=>:cascade})
   -> 0.0256s
-- create_table("plans", {:id=>:uuid, :default=>#<Proc:0x00007f17a0147918 /app/db/migrate/20220525122759_init_schema.rb:188 (lambda)>, :force=>:cascade})
   -> 0.0307s
-- create_table("subscriptions", {:id=>:uuid, :default=>#<Proc:0x00007f17a0140938 /app/db/migrate/20220525122759_init_schema.rb:204 (lambda)>, :force=>:cascade})
   -> 0.0229s
-- create_table("users", {:id=>:uuid, :default=>#<Proc:0x00007f17a00cbc28 /app/db/migrate/20220525122759_init_schema.rb:219 (lambda)>, :force=>:cascade})
   -> 0.0143s
-- add_foreign_key("add_ons", "organizations")
   -> 0.0054s
-- add_foreign_key("billable_metrics", "organizations")
   -> 0.0043s
-- add_foreign_key("charges", "billable_metrics")
   -> 0.0040s
-- add_foreign_key("charges", "plans")
   -> 0.0041s
-- add_foreign_key("credits", "applied_coupons")
   -> 0.0036s
-- add_foreign_key("credits", "invoices")
   -> 0.0041s
-- add_foreign_key("customers", "organizations")
   -> 0.0035s
-- add_foreign_key("events", "customers")
   -> 0.0034s
-- add_foreign_key("events", "organizations")
   -> 0.0039s
-- add_foreign_key("fees", "charges")
   -> 0.0034s
-- add_foreign_key("fees", "invoices")
   -> 0.0039s
-- add_foreign_key("fees", "subscriptions")
   -> 0.0039s
-- add_foreign_key("invoices", "subscriptions")
   -> 0.0032s
-- add_foreign_key("memberships", "organizations")
   -> 0.0039s
-- add_foreign_key("memberships", "users")
   -> 0.0040s
-- add_foreign_key("plans", "organizations")
   -> 0.0033s
-- add_foreign_key("subscriptions", "customers")
   -> 0.0043s
-- add_foreign_key("subscriptions", "plans")
   -> 0.0043s
== 20220525122759 InitSchema: migrated (0.5539s) ==============================

I, [2024-07-05T19:58:50.581536 #131]  INFO -- : Migrating to CreateAppliedAddOns (20220526101535)
== 20220526101535 CreateAppliedAddOns: migrating ==============================
-- create_table(:applied_add_ons, {:id=>:uuid})
   -> 0.0398s
== 20220526101535 CreateAppliedAddOns: migrated (0.0399s) =====================

I, [2024-07-05T19:58:50.629006 #131]  INFO -- : Migrating to AddMetadataToEvents (20220530091046)
== 20220530091046 AddMetadataToEvents: migrating ==============================
-- add_column(:events, :metadata, :jsonb, {:null=>false, :default=>{}})
   -> 0.0100s
== 20220530091046 AddMetadataToEvents: migrated (0.0101s) =====================

I, [2024-07-05T19:58:50.646858 #131]  INFO -- : Migrating to AddAddOnToFees (20220601150058)
== 20220601150058 AddAddOnToFees: migrating ===================================
-- add_reference(:fees, :applied_add_on, {:type=>:uuid, :foreign_key=>true, :index=>true})
   -> 0.0208s
== 20220601150058 AddAddOnToFees: migrated (0.0210s) ==========================

I, [2024-07-05T19:58:50.675777 #131]  INFO -- : Migrating to AddBillChargesMonthlyToPlans (20220602145819)
== 20220602145819 AddBillChargesMonthlyToPlans: migrating =====================
-- add_column(:plans, :bill_charges_monthly, :boolean)
   -> 0.0072s
== 20220602145819 AddBillChargesMonthlyToPlans: migrated (0.0074s) ============

I, [2024-07-05T19:58:50.691354 #131]  INFO -- : Migrating to AddChargesFromDateOnInvoices (20220607082458)
== 20220607082458 AddChargesFromDateOnInvoices: migrating =====================
-- add_column(:invoices, :charges_from_date, :date)
   -> 0.0069s
== 20220607082458 AddChargesFromDateOnInvoices: migrated (0.0069s) ============

I, [2024-07-05T19:58:50.705939 #131]  INFO -- : Migrating to CreatePaymentProviders (20220609080806)
== 20220609080806 CreatePaymentProviders: migrating ===========================
-- create_table(:payment_providers, {:id=>:uuid})
   -> 0.0228s
== 20220609080806 CreatePaymentProviders: migrated (0.0229s) ==================

I, [2024-07-05T19:58:50.736166 #131]  INFO -- : Migrating to CreatePaymentProviderCustomers (20220610134535)
== 20220610134535 CreatePaymentProviderCustomers: migrating ===================
-- create_table(:payment_provider_customers, {:id=>:uuid})
   -> 0.0383s
== 20220610134535 CreatePaymentProviderCustomers: migrated (0.0384s) ==========

I, [2024-07-05T19:58:50.782597 #131]  INFO -- : Migrating to AddPaymentProviderToCustomers (20220610143942)
== 20220610143942 AddPaymentProviderToCustomers: migrating ====================
-- add_column(:customers, :payment_provider, :string)
   -> 0.0057s
== 20220610143942 AddPaymentProviderToCustomers: migrated (0.0058s) ===========

I, [2024-07-05T19:58:50.796451 #131]  INFO -- : Migrating to AddInvoiceTypeToInvoices (20220613130634)
== 20220613130634 AddInvoiceTypeToInvoices: migrating =========================
-- add_column(:invoices, :invoice_type, :integer, {:null=>false, :default=>0})
   -> 0.0081s
== 20220613130634 AddInvoiceTypeToInvoices: migrated (0.0081s) ================

I, [2024-07-05T19:58:50.811793 #131]  INFO -- : Migrating to AddStatusToInvoices (20220614110841)
== 20220614110841 AddStatusToInvoices: migrating ==============================
-- add_column(:invoices, :status, :integer, {:null=>false, :default=>0})
   -> 0.0107s
== 20220614110841 AddStatusToInvoices: migrated (0.0109s) =====================

I, [2024-07-05T19:58:50.830901 #131]  INFO -- : Migrating to CreatePayments (20220617124108)
== 20220617124108 CreatePayments: migrating ===================================
-- create_table(:payments, {:id=>:uuid})
   -> 0.0422s
== 20220617124108 CreatePayments: migrated (0.0423s) ==========================

I, [2024-07-05T19:58:50.881349 #131]  INFO -- : Migrating to AddInvoiceFieldsToOrganizations (20220620141910)
== 20220620141910 AddInvoiceFieldsToOrganizations: migrating ==================
-- change_table(:organizations, {:bulk=>true})
   -> 0.0075s
== 20220620141910 AddInvoiceFieldsToOrganizations: migrated (0.0076s) =========

I, [2024-07-05T19:58:50.896124 #131]  INFO -- : Migrating to AddSlugToCustomers (20220620150551)
== 20220620150551 AddSlugToCustomers: migrating ===============================
-- change_table(:customers, {:bulk=>true})
   -> 0.0064s
W, [2024-07-05T19:58:51.111606 #131]  WARN -- : Scoped order is ignored, it's forced to be batch order.
bin/rails aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

PG::DuplicatePstatement: ERROR:  prepared statement "a1" already exists
/app/lib/tasks/customers.rake:6:in `block (2 levels) in <main>'
/app/db/migrate/20220620150551_add_slug_to_customers.rb:11:in `change'

Caused by:
ActiveRecord::StatementInvalid: PG::DuplicatePstatement: ERROR:  prepared statement "a1" already exists (ActiveRecord::StatementInvalid)
/app/lib/tasks/customers.rake:6:in `block (2 levels) in <main>'
/app/db/migrate/20220620150551_add_slug_to_customers.rb:11:in `change'

Caused by:
PG::DuplicatePstatement: ERROR:  prepared statement "a1" already exists (PG::DuplicatePstatement)
/app/lib/tasks/customers.rake:6:in `block (2 levels) in <main>'
/app/db/migrate/20220620150551_add_slug_to_customers.rb:11:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
root@38c541a217ca:/app/scripts# env | grep -i schema
POSTGRES_SCHEMA=lago_db

Hope that would be of help!

@alexander-potemkin
Copy link

I guess I've found the root case and I guess I shall give up with running Lago against external database - modifying database.yml every time doesn't feel to be practical.

ancorcruz pushed a commit that referenced this issue Jul 7, 2024
## Context

This PR is a fix for
#1945 (comment)

## Description

Lago startup script is relying on the `rails db:migrate:primary` to
perform the migration at startup.

Since in some situation, only one database is configured in the
`database.yml` file, the command is failing with the following error:
```
Unrecognized command "db:migrate:primary" (Rails::Command::UnrecognizedCommandError)
Did you mean?  db:migrate:up
```

This PR fixes this by using `rails db:migrate` instead when only one
database is present.
@vincent-pochet
Copy link
Collaborator

Thanks for all the details @alexander-potemkin

Good to know about the permissions. We will update the documentation with more details to help future users.

Regarding the issue, you can probably try to disable prepared statements by setting DATABASE_PREPARED_STATEMENTS environment variable to false

@alexander-potemkin
Copy link

@vincent-pochet , apologies for the delay in getting back to you. DATABASE_PREPARED_STATEMENTS indeed works, when setup as environment for api containers.

non-public schema works as well - thank you! The only problem seems to be somewhere around Redis cache - I've just migrated test environment to another database and I'm getting random errors saying that table doesn't exist. It's resolved with docker restart and when it's not - with redis cache cleanup. At least it seems like so for now.

@alexander-potemkin
Copy link

Shall anyone follow this thread: it seems like using anything except then public is a bad idea. In my case, lago-api was not able to find users table anymore, without me touching anything at all.

The solution was to restart the service and immediately everything went back to normal.

So, guess it's better stick to something that is well tested - public: ALTER SCHEMA "lago" RENAME TO "public"; with appropriate config changes.

@vincent-pochet
Copy link
Collaborator

Thank you @alexander-potemkin for these feedback
We are taking note of it and will be working on improving the handling of database schema

@alexander-potemkin
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants