Doctrine. Injecting additional parameter into dbal configuration - php

I have MySQL cluster with master server and 4 slaves.
The site based on Symfony3, Doctrine is used as ORM and DBAL.
My config for Doctrine looks like this:
doctrine:
dbal:
default_connection: default
connections:
default:
dbname: "%default_db_master_name%"
host: "%default_db_master_host%"
port: "%default_db_master_port%"
user: "%default_db_master_user%"
password: "%default_db_master_password%"
charset: UTF8
driver: "%default_db_master_driver%"
logging: "%kernel.debug%"
profiling: "%kernel.debug%"
wrapper_class: AppBundle\Connection\AppMasterSlaveConnection
mapping_types:
enum: string
slaves:
slave1:
host: "%default_db_slave1_host%"
port: "%default_db_slave_port%"
dbname: "%default_db_slave_name%"
user: "%default_db_slave_user%"
password: "%default_db_slave_password%"
slave2:
host: "%default_db_slave2_host%"
port: "%default_db_slave_port%"
dbname: "%default_db_slave_name%"
user: "%default_db_slave_user%"
password: "%default_db_slave_password%"
I would like to add weights for slaves, because they hardware is not equal, some of them are more productive, some less.
Also I would like to inject memcache service (or inject params for creating cache service object) for putting temporarely dns which are overloaded by requests and give them chance to back to normal.
For example, I want to inject weight param for slaves following way:
slave1:
host: "%default_db_slave1_host%"
port: "%default_db_slave_port%"
dbname: "%default_db_slave_name%"
user: "%default_db_slave_user%"
password: "%default_db_slave_password%"
weight: "%default_db_slave1_weight%"
slave2:
host: "%default_db_slave2_host%"
port: "%default_db_slave_port%"
dbname: "%default_db_slave_name%"
user: "%default_db_slave_user%"
password: "%default_db_slave_password%"
weight: "%default_db_slave2_weight%"
When I add this option, I receive an error
InvalidConfigurationException in ArrayNode.php line 317:
Unrecognized option "weight" under "doctrine.dbal.connections.default.slaves.slave1"
I don't know how to do it. I have just one idea, transfer all these params via Driver options,something like this
logging: "%kernel.debug%"
profiling: "%kernel.debug%"
wrapper_class: AppBundle\Connection\AppMasterSlaveConnection
options:
slave1: 5
slave2: 25
slave3: 45
slave4: 25
cache: '%memcached_db%'
mapping_types:
enum: string
slaves:
slave1:
But it looks awful.
Help me please.

Related

No transport supports the given Messenger DSN doctrine

I am getting an error No transport supports the given Messenger DSN "doctrine://default" when executing command messenger:setup-transports for Symfony messenger.
Handling messages synchronously for the message, handler, and dispatcher works.
Symfony: 4.4.2
Symfony/messenger: 4.4
doctrine/orm: 2.7
messenger.yml
messenger:
default_bus: messenger.bus.default
transports:
async: 'doctrine://default'
doctrine.yml
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
port: "%database_port%"
host: "%database_host%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"

Symfony 4 Doctrine 2, Mapping entity, error table has no primary key,

A symfony noob here. Been trying since morning to map entity/s of the database using Doctrine via console throws up no primary key error. The mysql server is a remote one which I unfortunately only have read access and I am not able to create a primary key. I did see a few questions on SO with the exact same issue but they were unanswered and old.
I tried https://medium.com/#joaoneto/solves-doctrine-orm-error-with-tables-without-primary-key-on-mysql-when-mapping-the-database-1ce740610b51
but again it throws up error regarding empty columns.
Call to a member function getColumns() on null
My doctrine.yaml. Obviously I altered the connection details.
doctrine:
dbal:
default_connection: default
connections:
# configure these for your database server
default:
driver: 'pdo_mysql'
host: 'localhost'
port: '3306'
dbname: 'symfony_test_db'
user: 'root'
password: ''
charset: utf8mb4
customer:
driver: 'pdo_mysql'
host: 'xxx.xxx.xx.xxx'
port: '3306'
dbname: 'sg3_symfony_db'
user: 'sguser'
password: 'password'
charset: UTF8
backoffice:
driver: 'pdo_mysql'
host: 'localhost'
port: '3306'
dbname: 'back_office'
user: 'backoffice_user'
password: 'password'
charset: UTF8
one:
driver: 'pdo_mysql'
host: 'xxx.xxx.xx.xxx'
port: '3306'
dbname: 'one_db'
user: 'one_user'
password: 'password'
charset: UTF8
staging:
driver: 'pdo_mysql'
host: 'xxx.xxx.xx.xxx'
port: '3306'
dbname: 'staging'
user: 'staginguser'
password: 'password'
charset: UTF8
# With Symfony 3.3, remove the `resolve:` prefix
#url: '%env(resolve:DATABASE_URL)%'
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
#auto_mapping: true
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Main'
prefix: 'App\Entity\Main'
alias: Main
customer:
connection: customer
mappings:
Customer:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Customer'
prefix: 'App\Entity\Customer'
alias: Customer
backoffice:
connection: backoffice
mappings:
Backoffice:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Backoffice'
prefix: 'App\Entity\Backoffice'
alias: Backoffice
one:
connection: mt4
mappings:
One:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/One'
prefix: 'App\Entity\One'
alias: One
staging:
connection: staging
mappings:
staging:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Staging'
prefix: 'App\Entity\Staging'
alias: Staging
CLI command I use to map but fails.
php bin/console doctrine:mapping:convert --from-database annotation --force --em=one ./src/Entity/One/ --verbose
In this case, sometimes you need to walk around.
This error:
Table ____ has no primary key. Doctrine does not support reverse
engineering from tables that don’t have a primary key.
So.
Doctrine can not work on tables that have no primary key.
In MySQL, create tables without PK will always be a bad idea, but, in some cases (or legacy systems) that not have PKs on some tables, you still can use Doctrine as ORM.
However, by default (and I believe this will not change) if your database has tables without primary key Mapping simply will not work.
The more fast way to solve this is override the vendor class DatabaseDriver, in the namespace:
namespace Doctrine\ORM\Mapping\Driver;
On line 289, change:
if ( ! $table->hasPrimaryKey()) {
continue;
// throw new MappingException(
// "Table " . $table->getName() . " has no primary key. Doctrine does not ".
// "support reverse engineering from tables that don't have a primary key."
// );
}
To avoid any future problems, after mapping your database, return the settings to avoid any problems later.
Good luck!
Reference: Solves Doctrine ORM Error with tables without Primary Key on MySQL when mapping the database.
Not a very clean solution but for the moment I managed to do it by, exporting the schema of tables I need and recreating them on my local server. Forcing Pk's on the tables that did not have PK defined. This created entity class files instantly and worked like a charm.

Codeception acceptance tests with Symfonys MasterSlaveConnection throws Exception

I'm using codeception (acceptance tests) in combination with the Symfony and Doctrine2 modules.
When I configure Symfony to use a single database connection, everything works fine and my tests finish. But as soon as I add database slave connections, the following exception appears and the test failes:
1) SomeCest: Some test
Test tests/acceptance/SomeCest.php:someTest
[PHPUnit\Framework\Exception] Undefined property: Doctrine\DBAL\Connections\MasterSlaveConnection::$_conn
#1 /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connections/MasterSlaveConnection.php:154
#2 Codeception\Subscriber\Module->before
#3 /var/www/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:184
#4 /var/www/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:46
I cannot understand how this error arises, because in the stated file (MasterSlaveConnection.php) the class is clearly extended from Connection, in which the property $_conn is defined.
Can someone help me with that? Is this a bug and I should open up a bug report on the codeception github page? Or am I doing something wrong? Thank you in advance!
acceptance.suite.yml:
actor: AcceptanceTester
modules:
enabled:
- Symfony:
part: SERVICES
environment: 'prod'
- Doctrine2:
depends: Symfony
cleanup: false
- WebDriver:
url: 'http://localhost/'
browser: phantomjs
restart: true
clear_cookies: true
log_js_errors: true
window_size: 1960x1080
app/config/config.yml with single database configuration:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
app/config/config.yml with multiple database configuration:
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
slaves:
slave1:
host: "%database_host2%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
slave2:
host: "%database_host3%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
I'm using symfony 2.8.25 and codeception 2.3.4

The class 'ScheduleBundle\Entity\schedule' was not found in the chain configured namespaces StudentsBundle\Entity

I am making a application with multiply bundels and database connections.
I keep getting this error:
The class 'ScheduleBundle\Entity\schedule' was not found in the chain configured namespaces StudentsBundle\Entity
500 Internal Server Error - MappingException
Here is the code from the controller
<?php
namespace ScheduleBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
//Json Response
use Symfony\Component\HttpFoundation\JsonResponse;
//Class Controller
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
//Request
use Symfony\Component\HttpFoundation\Request;
use ScheduleBundle\Entity\schedule;
class ApiController extends Controller
{
/**
* #Route("/api/{week}")
*/
public function roosterApi(Request $request, $week)
{
$rooster = array('week' => '1');
$entityManager = $this->get('doctrine')->getManager();
$roosterConnection = $this->get('doctrine')->getRepository('ScheduleBundle:schedule', 'schedule');
$dataRooster = $roosterConnection->findOneByStudentId('36838');
$dataRooster->setSchedule($rooster);
$entityManager->persist($dataRooster);
$entityManager->flush();
$out = array('1' => $week);
return new JsonResponse($out, 200, array('Content-Type' => 'application/json'));
}
}
?>
I think the problem is with my orm mapping so i include the doctrine code from config.yml
# Doctrine Configuration
doctrine:
dbal:
default_connection: StudentDB
connections:
StudentDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_students%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
TeacherDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_teachers%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
GradesDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_grades%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
ScheduleDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_schedule%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
SpecialGroupDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_specialgroup%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
ToDoListDB:
driver: '%database_driver%'
host: '%database_host%'
port: '%database_port%'
dbname: '%database_todolist%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
orm:
default_entity_manager: students
entity_managers:
students:
connection: StudentDB
mappings:
StudentsBundle: ~
teachers:
connection: TeacherDB
mappings:
TeachersBundle: ~
grades:
connection: GradesDB
mappings:
GradesBundle: ~
schedule:
connection: ScheduleDB
mappings:
ScheduleBundle: ~
specialgroup:
connection: SpecialGroupDB
mappings:
SpecialGroupBundle: ~
todolist:
connection: ToDoListDB
mappings:
ToDoListBundle: ~
I am using symfony 3.0.3 and doctrine
edit: changed use ScheduleBundle\Entity to use ScheduleBundle\Entity\schedule this did not fix the problem
You need to use the correct doctrine entity manager service. In your code you refer to the doctrine service which is an alias of the default entity manager. For the schedule entity manager you need to use the following service:
doctrine.orm.schedule_entity_manager
So try using this:
$this->get('doctrine.orm.schedule_entity_manager')
Instead of this:
$this->get('doctrine')
For dump current service definition you can use the console command:
app/console debug:container |grep entity
Hope this help

Doctrine connection with db

I am about to start a project in doctrine symfony, but I have to make connection with multiple databases. One of them is an existing database (SQL SERVER) that cannot be mapped with ORM. Is there any possibility to connect with this db with another db that is NOT mapped in doctrine and work with controllers normally?
I develop a multi-database sf2 app with doctrine2 orm mapping.
We use intellectsoft-uk/MssqlBundle
Our configuration is:
config.yml
# Doctrine Configuration
doctrine:
dbal:
default_connection: acme_mysql
connections:
acme_mysql:
host: %acme_mysql_database_host%
port: %acme_mysql_database_port%
dbname: %acme_mysql_database_name%
user: %acme_mysql_database_user%
password: %acme_mysql_database_password%
charset: UTF8
acme_slqsrv:
driver: sqlsrv
driver_class: \Realestate\MssqlBundle\Driver\PDODblib\Driver
host: %acme_slqsrv%
port: %acme_slqsrv%
dbname: %acme_slqsrv%
user: %acme_slqsrv%
password: %acme_slqsrv%
charset: UTF8
orm: #optional if you want to map some entity in doctrine2
auto_generate_proxy_classes: %kernel.debug%
default_entity_manager: acme_mysql
entity_managers:
em_mysql:
connection: acme_mysql
mappings:
AcmeMysqlBundle: ~
em_sqlsrv:
connection: acme_sqlsrv
mappings:
AcmeSqlSrvBundle: ~
This configuration permit you to take a connection instance in a controller/service and use it for access database and execute stored procedures and so on...
Hope this help

Categories