Set a timeout for database connection with Doctrine - symfony

Is it somehow possible to set a connection timeout in Doctrine (for MySQL)?
I would like to set a 5 sec. timeout for my connections.

You'll need to specify the driver option for connection timeouts in your services.yaml configuration for doctrine dbal (seeing your symfony tag).
If you're using mysqli extension:
doctrine:
dbal:
...
options:
0: 5 // '0' is the value of 'MYSQLI_OPT_CONNECT_TIMEOUT'
For PDO-based drivers:
doctrine:
dbal:
...
options:
2: 5 // '2' is the value of 'PDO::ATTR_TIMEOUT'
References:
https://symfony.com/doc/master/reference/configuration/doctrine.html#doctrine-dbal-configuration
https://www.doctrine-project.org/projects/doctrine-dbal/en/2.10/reference/configuration.html
https://www.php.net/manual/en/mysqli.options.php
https://www.php.net/manual/en/pdo.constants.php#pdo.constants.attr-timeout

If you're finding this question and using SQL Server:
I'm using SQL Server, not MySQL, with a PDO driver, Symfony 5, and Doctrine ORM 2.7.4.
Using PDO enum values in the services.yaml as suggested in this answer did not work; the initial connection times out after 30 seconds regardless of the value I set with PDO::ATTR_TIMEOUT.
Instead, the LoginTimeout value can be used:
doctrine:
dbal:
...
options:
LoginTimeout: 5
Note that the options set in the YAML here are passed into the $dnsOptions array used to construct the $dsn in PDOSqlsrv/Driver::_constructPdoDsn(), so setting a raw PDO enum value (2=5, as in the linked answer, for example) may not be what you want do.

Maybe you can use something like set_time_limit() into your script execution

Related

Doctrine query_cache auto expire

I'm using symfony 3.4 + doctrine + redis by using the composer bundle sncRedisBundle
In my config.yml I enabled doctrine query cache:
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
auto_mapping: false
metadata_cache_driver: redis
query_cache_driver: redis
result_cache_driver: redis # !!!
snc_redis:
clients:
doctrine:
type: predis
alias: doctrine_redis
dsn: "%redis_dsn_doctrine%"
logging: false
options:
connection_persistent: true
doctrine:
query_cache: #!!!!!!!!
#it caches the translation from Doctrine's DQL into SQL.
client: doctrine_redis
namespace: shop_doctrine_query
entity_manager: [default, legacy]
The keys set by doctrine for it's result_cache never expire:
How can I call automatically \Doctrine\ORM\Query::setQueryCacheLifetime or make that cache expire. (Note I don't have access to set redis eviction policies on this server).
I think that Doctrine query cache lifetime aren't configured in the doctrine package nor in the redis package, but in the framework package, where you set your pool of cache.
You should have a look on this issue where a user is asking how to configure RedisCluster with Doctrine Cache. B-Galati answers with a configuration example where it defines lifetime for doctrine result cache.
Could you try something like:
framework:
cache:
pools:
cache.doctrine.orm.default.query: ## I'm not sure of this name
adapter: cache.app
default_lifetime: 25200 # 1 week
Or
framework:
cache:
pools:
doctrine.query_cache_pool:
adapter: cache.app
default_lifetime: 25200 # 1 week
The symfony console cache:pool:list command could help you to identify your pools and the symfony console cache:pool:prune could help you to see if out of date queries are well deleted.

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

Symfony2 test parameters

Is there a way to configure test parameters with Symfony2?
I tried importing parameters_test.yml from the config_test.yml file but the variables still come from the parameters.yml file which is imported by config.yml which is imported by config_dev.yml which is imported by config_test.yml.
Basically I want to setup different variables in a test parameter file so I can access the values and also use them in the config files. If I hardcode the variables directly into config_test.yml I don't have access to them.
The variable I'm interested in particular is database_name or doctrine->dbal->dbname.
Thanks
Of course ensure your two first lines your config_test.yml are:
imports:
- { resource: config_dev.yml }
- { resource: parameters_test.yml }
In config_test.yml simple write this configuration:
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver_test%
host: %database_host_test%
port: %database_port_test%
dbname: %database_name_test%
user: %database_user_test%
password: %database_password_test%

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

Symfony2 configure DB storage sessions

UPDATE: problem solved, see the comments (many issues, the versions differences was but one of them).
I'm trying to configure sessions in Symfony2 in config.yml file. I have the following configuration:
session:
default_locale: %locale%
lifetime: 7200
auto_start: true
storage_id: session.storage.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
pdo:
class: PDO
arguments:
- "mysql:dbname=%database_name%"
- %database_user%
- %database_password%
session.storage.pdo:
class: Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
It's based on Symfony2's cookbook http://symfony.com/doc/2.0/cookbook/configuration/pdo_session_storage.html
I've created exactly the same table as in the given link.
However, it doesn't work. I get some "blank" error (no error message, but "PDO Exception" and "Error Exception"). I admit I have no much knowledge on configuring the Symfony2 or any info (that's why I'm using cookbook). I lost a lot of time and see no much documentation about it in the internet, not mentioning the fact that internet is quite silent about this case (having session storaged to DB table in Symfony2).
My NetBeans is "shouting" sth about the last line:
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
"ScannerException while scanning for the next token we had this found character #(64) that cannot start any token".
UPDATE:
Hmm now I'm not sure if it's about the configuration. I can see that Symfony2's cookbook (use... ) example doesn't match actually the file structure in the Symfony2's bundle. In a word, there is no such file-path, but after putting the real one it still doesn't work.
I had the same problem as you with Symfony 2.5. Turns out my solution was to disable session.auto_start in php.ini. The PdoSessionStorage will not take over if the session is being started before PDO has the opportunity to take control of it. I had overlooked this at first because I was modifying the wrong one (I had two copies of php.ini). To check if this is the problem on yours, run this command:
echo ini_get('session.auto_start');
If that returns a '1' or a 'true', then be sure to set this in your php.ini:
session.auto_start = 0
So for reference, here is my setup with Symfony 2.5 to make this work:
config.yml
framework:
session:
handler_id: session.handler.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["#pdo", "%pdo.db_options%"]
pdo:
class: PDO
arguments:
dsn: "mysql:host=%database_host%;port=%database_port%;dbname=%database_name%"
user: "%database_user%"
password: "%database_password%"
calls:
- [setAttribute, [3, 2]] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION

Resources