SQLite environment for Symfony 4.1 - symfony

On a brand new project (Symfony 4.1), I tried to work with a SQLite database.
So I change the .env as it said :
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Configure your db driver and server_version in config/packages/doctrine.yaml
#DATABASE_URL=mysql://db_user:db_password#127.0.0.1:3306/db_name
DATABASE_URL=sqlite:///%kernel.project_dir%/var/data.db
###< doctrine/doctrine-bundle ###
File doctrine.yaml look like
parameters:
# Adds a fallback DATABASE_URL if the env var is not set.
# This allows you to run cache:warmup even if your
# environment variables are not available yet.
# You should not need to change this value.
env(DATABASE_URL): ''
doctrine:
dbal:
# configure these for your database server
driver: 'pdo_sqlite'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: '%env(resolve:DATABASE_URL)%'
But when I try to create the database :
php bin/console doctrine:database:create
This error occurs :
In CreateDatabaseDoctrineCommand.php line 78:
Connection does not contain a 'path' or 'dbname' parameter and cannot be dropped.
The fact is that url: '%env(resolve:DATABASE_URL)%' can't recursivly resolve the %kernel.project_dir% part of my .env config.
It seems to be a known issue that has been fixed for Symfony 3.4 in 2017 (So I can bet that has been fixed for more recent branches like 4.1 since 2017)
Interresting Source :
https://github.com/symfony/flex/issues/129
https://github.com/symfony/symfony/pull/23901
Please note that I found 2 workarounds in file doctrine.yaml :
parameters:
# Adds a fallback DATABASE_URL if the env var is not set.
# This allows you to run cache:warmup even if your
# environment variables are not available yet.
# You should not need to change this value.
env(DATABASE_URL): 'sqlite:///%kernel.project_dir%/var/data.db'
But cleary (as mentioned) I should not modify that parameter...
Or
doctrine:
dbal:
# configure these for your database server
driver: 'pdo_sqlite'
server_version: '5.7'
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
url: 'sqlite:///%kernel.project_dir%/var/data.db'
Of course, it is more clean to fill in the sqlite connexion string in .env file than doctrine.yaml file because it depends on environment settings...
Do you have any idea how to make it works in .env file ?

Related

Symfony: The class XYZ was not found in the chain configured namespaces

Existing questions did not help.
I am still learning Symfony and setting up an existing project. Trying to run doctrine fixtures from my application directory.
./app/console doctrine:fixtures:load --env test
And running this gives me following errors
Error thrown while running command "doctrine:fixtures:load --env test --em default". Message: "The class 'ClientPortal\GenericBundle\Document\Accountant' was not found in the chain configured namespaces _XyzProjectName\CalendarContext\Domain\Model, Integration\GetFeedbackBundle\Model, _XyzProjectName\AccountingProcessContext\Domain\Model, _XyzProjectName\CaseContext\Domain" {"exception":"[object] (Doctrine\Common\Persistence\Mapping\MappingException(code: 0): The class 'ClientPortal\GenericBundle\Document\Accountant' was not found in the chain configured namespaces _XyzProjectName\CalendarContext\Domain\Model, Integration\GetFeedbackBundle\Model, _XyzProjectName\AccountingProcessContext\Domain\Model, _XyzProjectName\CaseContext\Domain at /usr/local/var/www/1800-api/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php:22)
And this exception is being thrown when trying to persist object of class
'ClientPortal\GenericBundle\Document\Accountant'
and here is my doctrine in config.yml
doctrine:
dbal:
driver: pdo_pgsql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
mappings:
CalendarBundle:
prefix: '_XyzProjectName\CalendarContext\Domain\Model'
IntegrationGetFeedbackBundle:
prefix: 'Integration\GetFeedbackBundle\Model'
AccountingProcessBundle:
prefix: '_XyzProjectName\AccountingProcessContext\Domain\Model'
CaseBundle:
prefix: '_XyzProjectName\CaseContext\Domain'
GenericBundle:
type: "annotation"
prefix: 'ClientPortal\GenericBundle\Document'
dir: 'src'
is_bundle: false
The snippet which is raising this exception
$account = new ClientPortal\GenericBundle\Document\Accountant();//full namespace added for clarity - also this file lies in the same directory structure.
$account->setSfAccountantId($accountantId);
$account->setUsername($username);
$manager = new ObjectManager;
$manager->persist( $account ); //This throws the above mentioned exception
My thought is, the file ClientPortal\GenericBundle\Document\Accountant.php is being autoloaded as there is no exception thrown at the time of instantion of its object. But, there is something missing with configuration or mapping because of which doctrine does not know how to persist its object.
[Source code][1] Accountant class
GenericBundle(s) registered under AppKernel
new Website\GenericBundle\WebsiteGenericBundle(),
new Admin\GenericBundle\AdminGenericBundle(),
new ClientPortal\GenericBundle\ClientPortalGenericBundle(),
new TaxApp\GenericBundle\TaxAppGenericBundle(),
So, as I suggested in comments - try to add ClientPortal\GenericBundle\Document\ namespace to mappings in your doctrine config file, like that:
#...
orm:
auto_generate_proxy_classes: "%kernel.debug%"
mappings:
# ...
ClientPortalGenericBundle:
type: annotation
prefix: 'ClientPortal\GenericBundle\Document\'
dir: '%kernel.root_dir%/src/ClientPortal/GenericBundle/Document/'
#is_bundle: false
auto_mapping: true
Had the same issue with Symfony 4 while using multiple database connections. This one https://stackoverflow.com/a/55361742/2540699 helped me to solved my problem.
I bumped into this kind of message in my Symfony 6.1 project, using multiple entity managers, with one of the entity managers specified as default in doctrine.yaml:
doctrine:
orm:
default_entity_manager: general
entity_managers:
general:
# config for general
other_entity_manager:
# config for other entity manager
Everything was fine on my dev environment, but on production I got the error
Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "The class XXX was not found in the chain configured namespaces " at /opt/approot/current/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php
Problem seemed to be that I have a when#prod: section in my doctrine.config.yml. It seems I had to repeat the default_entity_manager over there:
when#prod:
doctrine:
orm:
default_entity_manager: general
# other prod-specific configuration
This fixed it for me.
Update: This is probably related to this issue: https://github.com/symfony/symfony/issues/27769

Can one use different database credentials for Doctrine migrations in Symfony2?

How can one configure Symfony's DoctrineMigrationsBundle to use different database authentication credentials to its DoctrineBundle—or at very least, a different DoctrineBundle connection to that used elsewhere in the app?
We would like the app to connect to the database with only limited permissions, e.g. no ability to issue DDL commands such as CREATE, ALTER or DROP. However, migrations will need to execute such DDL commands and so should connect as a user with elevated permissions. Is this possible?
I know it's a very old post, but as it is the one which shows on a Google search on the subject, I add my solution, working with Symfony 4.
First, you just have to define a new database connection in config/doctrine.yml (a new entity manager is NOT needed):
doctrine:
dbal:
default_connection: default
connections:
default:
# This will be the connection used by the default entity manager
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_pgsql'
server_version: '11.1'
charset: UTF8
migrations:
# This will be the connection used for playing the migrations
url: '%env(resolve:DATABASE_MIGRATIONS_URL)%'
driver: 'pdo_pgsql'
server_version: '11.1'
charset: UTF8
orm:
# As usual...
You also have to define the DATABASE_MIGRATIONS_URL with the admin credentials in the .env file or in environnement variables:
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
DATABASE_URL=postgresql://app_user:app_user_pass#localhost:5432/db
# Database url used for migrations (elevated rights)
DATABASE_MIGRATIONS_URL=postgresql://admin_user:admin_user_pass#localhost:5432/db
###< doctrine/doctrine-bundle ###
Then, just execute your migrations with the --db option, passing the name of your new connection:
php bin/console doctrine:migrations:migrate --db=migrations
Yes. Just define a new entity manager with the correct connection details and then use that entity manager when running migration commands
$ php app/console doctrine:migrations:version --em=new_entity_manager

Unrecognized option "driver" under "sylius_money"

I have installed SyliusCartBundle following the docs and when I run "php app/console doctrine:schema:update --force" I get the following error:
[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]
Unrecognized option "driver" under "sylius_money"
My config.yml looks like in here http://sylius.readthedocs.org/en/latest/bundles/SyliusCartBundle/installation.html
#\app\config\config.yml
sylius_cart:
resolver: app.cart_item_resolver # The id of our newly created service.
classes: ~ # This key can be empty but it must be present in the configuration.
sylius_order:
driver: doctrine/orm
sylius_money:
driver: doctrine/orm
I've submitted a PR to update the docs for the Sylius CartBundle.
The configuration should be at its most simplistic:
sylius_money: ~
This equates to the default options, which are:
sylius_money:
currency: EUR
locale: en
However in Symfony, I'd recommend this setting:
sylius_money:
locale: %locale%
Where %locale% is the value taking from app/config/parameters.yml.

Symfony Doctrine generate entities from multiple databases

With Doctrine in Symfony2 there is a simple way to start a project with reverse-engineered Entities created from existing database schema. It is quite well documented here. There is not mentioned how to reverse-engineer data from a non-default database when using multiple databases (which is documented here).
I found the solution here, it works like this:
php app/console doctrine:mapping:convert --em="troller" --from-database yml ./src/NAMESPACE/NAMEBundle/Resources/config/doctrine/metadata/orm
However, I'm just getting the exception as if the second entity manager didn't exist. Even though I have config.yml according to docs.
[InvalidArgumentException]
Doctrine ORM Manager named "troller" does not exist.
Any ideas?
Did you specify an entity manager with "troller" name?
You can do this with a snippet of code like this (into app/config/config.yml file)
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
AcmeDemoBundle: ~
AcmeStoreBundle: ~
troller:
connection: troller
mappings:
YourTrollerBundle: ~
In this example, you've defined two entity managers called default and troller. The default entity manager manages entities in the AcmeDemoBundle and AcmeStoreBundle, while the troller entity manager manages entities in the YourTrollerBundle. You've also defined two connections, one for each entity manager.
Obiously define a new connection and entity manager, isn't enaugh: you have to specify "connection parameters" also (like db name, user, password, driver, and so on)
troller:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8

Doctrine2: How to set all tables to collate with UTF8

I am using Doctrine with Symfony2.
My config.yml file looks something like this:-
Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
Unfortunately my tables are not collating to the UTF8_general_ci or UTF8_unicode_ci
I tried
collate: utf8_unicode_ci
But Doctrine2 didn't recognize the option.
How can I achieve the same?
The behavior of collate has changed in doctrine: http://www.doctrine-project.org/jira/browse/DDC-2139
The collation is now set to utf8_unicode_ci if you don't specify anything at the table level. The way to go right now is to add it to options in your table declaration:
/**
* #ORM\Table(options={"collate"="utf8_swedish_ci"})
* #ORM\Entity
*/
This will generate the correct collation for the table:
$ php app/console doctrine:schema:update --dump-sql --env=test | grep swedish
... DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci ENGINE = InnoDB;
I've filed an issue for the documentation to be updated to reflect this behaviour.
The charset: UTF8 option is just useful to ask Doctrine to execute SET NAMES UTF-8 on each page. I don't have any specific configuration for Doctrine, and my tables are by default in utf8_general_ci InnoDB.
Read this part of the documentation: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/faq.html#how-do-i-set-the-charset-and-collation-for-mysql-tables, it answers your question:
You can’t set these values inside the annotations, yml or xml mapping
files. To make a database work with the default charset and collation
you should configure MySQL to use it as default charset, or create the
database with charset and collation details. This way they get
inherited to all newly created database tables and columns.
UPDATE:
See Symfony3.1 book for reference (click here):
Also notice the use of utf8mb4 instead of plain utf8. ("Symfony recommends utf8mb4 against MySQL's utf8 character set, since it does not support 4-byte unicode characters, and strings containing them will be truncated. This is fixed by the newer utf8mb4 character set.")
Setting UTF8 defaults for MySQL is as simple as adding a few lines to
your configuration file (typically my.cnf):
[mysqld]
# Version 5.5.3 introduced "utf8mb4", which is recommended
collation-server = utf8mb4_general_ci # Replaces utf8_general_ci
character-set-server = utf8mb4 # Replaces utf8
You can also change the defaults for Doctrine so that the generated
SQL uses the correct character set.
# app/config/config.yml
doctrine:
dbal:
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
I suggest you try add this setting to your Doctrine configuration:
options:
1002: "SET NAMES 'UTF8' COLLATE 'utf8_unicode_ci'"
So it looks like this:
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
options:
1002: "SET NAMES 'UTF8' COLLATE 'utf8_unicode_ci'"
As a reference Doctrine Configuration:
http://symfony.com/doc/2.0/reference/configuration/doctrine.html#reference-dbal-configuration
And in case you are using MySql:
http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html
BTW. I had problems with displaying polish characters and adding only set names without collation (as below) helped.
options:
1002: "SET NAMES 'UTF8'
Use code below to set collation, engine and charset (annotation example):
/**
* #ORM\Table(
* name="temporary",
* options={"collate":"utf8_general_ci", "charset":"utf8", "engine":"MyISAM"}
* )
* #ORM\Entity
*/
Source: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-column
You can refer to the documentation here http://dev.mysql.com/doc/refman/5.0/en/charset-applications.html if you are using ORMs like Doctrine.
Particularly: adding/editing the [mysqld] block in your my.cnf (usually found in /etc/my.cnf or xampp/mysql/my.cnf)
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
I've got this problems with fetching data which includes polish characters from database. It looks like:
effects of displaying data from db
my config.yml is like:
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
options:
1002: "SET NAMES 'UTF8'"
and I've been searching for an answer for couple of hours - Im so tired of this. "1002: SET NAMES 'utf8'" Doesnt work for me. But when I tryed to access my db from simple php script (out of symfony) the effect was the same but when I added line:
mysql_query("SET NAMES 'utf8'");
it worked properly. So it seems to be little strange. All the tables in my db have 'utf8_unicode_ci' set.
I met the same problems. By search the code, I find the code in
vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
if ( ! isset($options['collate'])) {
$options['collate'] = 'utf8_unicode_ci';
}
So I changed it to 'utf8_general_ci', and it worked. All of tables' collation changed to utf8_general_ci after rebuild, but I still have one question: when I changed the annotations, I got the following error message:
[Creation Error] The annotation #ORM\Table declared on class Gvsun\UserBundle\Entity\User does not have a property named "collation". Available properties: name, schema, indexes, uniqueConstraints, options
I search the documentation of Doctrine, but I didn't find the 'option' property, can someone tell me how to use options property, I think it might be able to change collate in annotations settings?
I create manually my data base with with UTF8 collate (ex. with phpmyadmin). If I do this, all tables create with command doctrine:schema:create will have collate utf8.
I have successfully used options: collate in YML configuration of Symfony 2.7.
MyBundle\Entity\Company:
type: entity
repositoryClass: MyBundle\Repository\CompanyRepository
table: company
options:
collate: utf8_general_ci
if you are looking for a way to have migrations be created correctly you should setup the connection
you can set the default_table_options connection option to achieve this:
in symfony this is done through:
doctrine:
dbal:
default_table_options:
charset: utf8
collate: utf8_general_ci
for those looking to do it in plain doctrine this translates to doctrine connection option defaultDatabaseOptions, and is passed to the entity manager together with your database credentials etc:
[
...
'driver' => ...
'user' => ...
...
'defaultDatabaseOptions' => [
'charset' => 'utf8',
'collate' => 'utf8_general_ci'
]
]
I had have the same problem, and after reading this documentation from doctrine project page I decided to abandon solution with yml file.
Since DoctrineBundle 2.0, utf8mb4 is the default value for MySQL. So, you don't need to configure anything anymore.
See https://github.com/doctrine/DoctrineBundle/blob/master/UPGRADE-2.0.md
#ORM\Table(name="user", options={"collate"="utf8_unicode_ci", "charset"="utf8 ", "engine"="InnoDB"})

Resources