Closed Bilge closed 2 years ago
Not able to reproduce this. The table clearly does exist:
> create table {{%fieldgroups}} ... done (time: 0.034s)
So it must just be a schema caching bug. Should be fixed for the next release, as the Install migration is now clearing schema caches after it finishes creating all the tables, and before it starts adding the default data.
To get the fix early, change your craftcms/cms
requirement in composer.json to "dev-develop as 3.7.26"
and run composer update
.
It still happens to me on dev-develop on Windows via mintty. I see absolutely no tables have been created in my database.
Also, I will add it is very frustrating to have to enter the same data at all 15 prompts every time I wish to test it. A few of the prompts load data from the previous run, but most don't (even if they did save it).
@Bilge Is this in WSL or are you using Cygwin?
Cygwin (Git Bash).
@Bilge curious... you can reproduce it on the native Windows host machine or in WSL?
Yes, the same thing happens under WSL1. I don't think this has anything to do with the platform.
@Bilge if you try it with a database name that doesn't have a space in it, do you get the same behavior? Foo\ Bar
No, if I use a database named test
, it works. It seems pretty clear, then, that the script cannot handle a database with a space in its name. Being as that's the case, I'm not sure why you cannot reproduce the issue.
I tested installation with a Postgres DB named Foo Bar
when looking into #10274 and it works fine on my end (using Nitro on macOS). So it’s not a problem with the Install migration or Yii.
Also, I will add it is very frustrating to have to enter the same data at all 15 prompts every time I wish to test it. A few of the prompts load data from the previous run, but most don't (even if they did save it).
You can skip most of them by running php craft install
rather than php craft setup
. setup
is mainly for storing the DB connection settings in your .env
file. Once they’ve been set correctly, there’s no need to keep re-setting them.
We just noticed you are using a custom schema name, craft
. There’s some nuance with using a non-public
schema which was not obvious from the nondescript “Database schema:” prompt: that setting is only for telling Craft what the default schema that Postgres is already configured to use is (via SHOW search_path
). It won’t actually inject the schema name into generated SQL queries to force it to be used. (See https://github.com/yiisoft/yii2/issues/12763 for a long discussion about this behavior.)
I’ve just dropped the “Database schema:” prompt in favor of some logic that determines which schema is actually likely to be used by default. The command will now simply output the result.
I also updated the command to start using existing environment variable values as the prompt defaults, if available.
End result looks like this:
> php craft setup/db-creds
connecting to craft3.nitro
Which database driver are you using? (mysql or pgsql) [pgsql]
Database server name or IP address: [postgres-13-5432.database.nitro]
Database port: [5432]
Database username: [nitro]
Use the password provided by $DB_PASSWORD? (yes|no) [yes]:
Database name: [Foo\ Bar]
Database table prefix:
Testing database credentials ... success!
Using default schema "craft".
Saving database credentials to your .env file ... done
If that's the case I can't even use this software whatsoever. As a matter of fact, the sole reason I picked this CMS was because it appeared to actually support Postgres schemas, which most other CMS completely omits support for. If that is not the case then is it worth me opening an issue to add this feature, or is it not something you care about?
To be clear, you can use a non-public
schema; you just need to configure Postgres to use it by default, via the search_path
setting.
Usually search_path
is set to "$user", public
by default. "$user"
refers to whotever the current user is.
So, if you want to give Craft its own schema without affecting the default schema for other applications, you just need to give Craft its own Postgres user, and then name a schema after it. For example, if the Postgres user is named craft
, it would use the craft
schema by default.
I do not wish to reconfigure the search path because that impacts queries. In particular, if a table is unprefixed, it is because I expect it to be found in the public schema, but if it is not, and it is instead found in the craft schema, it will now target the wrong table (and vice versa). The whole point of having a separate schema is to avoid name conflicts, but to add them all to the search path violates this benefit by potentially causing collisions again.
Another option is you could set the default schema for each new database connection, by adding this to config/app.php
:
use craft\db\Connection;
use craft\helpers\App;
use yii\base\Event;
return [
'components' => [
'db' => function() {
$config = App::dbConfig();
$config['on afterOpen'] = function(Event $event) {
/** @var Connection $db */
$db = $event->sender;
$schema = $db->schema->defaultSchema;
$db->createCommand("SET search_path TO $schema;")->execute();
};
return Craft::createObject($config);
},
],
];
It will add a new database query to every request, so it’s not ideal, but it works.
It will only affect connections created by Craft.
Yes, you're right, I redacted my comment because it was incorrect. Although it still seems incorrect to have to add this boilerplate to the config. Such functionality should be easy to enable in the software configuration. I mean, the previous assumption that specifying the schema you want to use would just work should ideally hold true.
I agree, and have voiced that opinion over at https://github.com/yiisoft/yii2/issues/12763, along with a suggested fix. Out of our direct control though.
(I’ve also considered adding a config setting that would run the above code automatically on connect, but it feels wrong to make it super easy to do something that causes an extra DB query per request, when the ideal solution would be to just reconfigure Postgres or use a username-based schema.
I disagree that it's such a bad thing to issue an extra query per request. It might feel wrong, but there is probably almost no practical reason not to do it, since such a query is likely to have very little measurable overhead at all (if any). Issuing extra connections would be a different story, but once a connection is established you should feel free to issue any configuration commands as required.
Fair enough… I was on the fence anyway. Just added a new setSchemaOnConnect
DB connection setting, which executes the SET search_path
command for you.
Composer-update to dev-develop
and add this to config/db.php
:
'setSchemaOnConnect' => true,
Craft 3.7.27 is out now with that new DB connection setting.
Description
./craft setup
fails on fresh install with:Steps to reproduce
./craft setup
Additional info