I have two database connections in config.yml and two entity managers. Each are tied to a bundle.
The issue that I'm having is running unit tests, which start by creating a blank db and loading in data. It's creating both databases but i'm getting both sets of tables in each database, instead of one set of entities in one db and one in the other. Since two db connections isn't incredibly common, I'm having trouble finding some help on this.
doctrine:
dbal:
default_connection: default
...
connections:
default:
(conectioninfo)
seconddb:
(connectioninfo)
orm:
default_entity_manager: default
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
connection: default
mappings:
MycompanyCoreBundle: ~
seconddb:
connection: seconddb
mappings:
MycomanySecondBundle: ~
When running unit tests, the lines I have are:
php app/console doctrine:database:drop --force --env=test --connection=default
php app/console doctrine:database:create --env=test --connection=default
php app/console doctrine:schema:drop --force --no-interaction --env=test --em=default
php app/console doctrine:schema:update --force --no-interaction --env=test --em=default
php app/console doctrine:database:drop --force --env=test --connection=seconddb
php app/console doctrine:database:create --env=test --connection=seconddb
php app/console doctrine:schema:drop --force --no-interaction --env=test --em=seconddb
php app/console doctrine:schema:update --force --no-interaction --env=test --em=seconddb
When running all this, the output is
Successfully deleted cache entries.
Dropping database schema...
Database schema dropped successfully!
Updating database schema...
Database schema updated successfully! "91" queries were executed
The problem is that those 91 queries are a combination of both Entity folders in the two bundles. I'm missing somewhere to point them separately so they go into their respective databases.
I found the answer to this eventually. There isn't a way to specify a database for a Migration, so you basically have to run Migration twice on EM and then test for the db connection.
Within each migration file, you put in a line to ignore it if it's not the correct one. Thus, some files have
$this->skipIf( $this->connection->getDatabase() != 'dbone', 'Skipping database.' );
and others have
$this->skipIf( $this->connection->getDatabase() != 'dbtwo', 'Skipping database.' );
Then when you run these commands:
doctrine:migrations:migrate --em="default"
doctrine:migrations:migrate --em="orm"
Both will cycle through all your migration files but the ones that don't apply to that situation will be ignored.
Related
Currently, I'm trying to set up a workflow with GitHub action.
I took example from https://github.com/shivammathur/setup-php/blob/master/examples/symfony-mysql.yml
My ci.yml is:
name: phpunit
on: [push]
jobs:
tests :
name: Running functional and unit test
runs-on: ubuntu-20.04
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
MYSQL_ROOT_PASSWORD: symfony
MYSQL_DATABASE: symfony
ports:
- 3306/tcp
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
fail-fast: true
matrix:
php-versions: ['7.4-apache']
steps:
# ββ Setup Github actions π βββββββββββββββββββββββββββββββββββββββββββββ
# https://github.com/actions/checkout (official)
- name: Checkout
uses: actions/checkout#v2
# https://github.com/shivammathur/setup-php (community)
- name: Setup PHP, extensions and composer with shivammathur/setup-php
uses: shivammathur/setup-php#v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring, xml, ctype, iconv, intl, pdo, pdo_mysql, dom, filter, gd, iconv, json, mbstring, mysqli
env:
update: true
- name: Check PHP Version
run: php -v
# ββ Composer π§βοΈ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- name: Validate composer.json and composer.lock
run: composer validate
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache#v1
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- run: composer require symfony/runtime
- name: Run Migration && Load Fixtures
run: |
composer require --dev symfony/orm-pack
php bin/console doctrine:database:drop --if-exists --force --env=test
php bin/console doctrine:database:create --if-not-exists --env=test
php bin/console doctrine:schema:update --env=test --force || echo "No migrations found or schema update failed"
php bin/console doctrine:migrations:migrate --env=test || echo "No migrations found or migration failed"
php bin/console doctrine:fixtures:load --no-interaction
env:
DATABASE_URL: mysql://root:symfony#127.0.0.1:${{ job.services.mysql.ports['3306'] }}/symfony
## ββ NPM π± ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- name: npm install
uses: actions/setup-node#v2
with:
node-version: '14'
#registry-url: npm.fontawesome.com
- run: npm install
#env:
#NODE_AUTH_TOKEN: ${{ secrets.FONTAWESOME_NPM_AUTH_TOKEN }}
- run: npm run build
- run: php bin/phpunit
I'm getting issue in the step of Run migrations & load Fixtures':
ci error:
Ci error:
Error: Migration DoctrineMigrations\Version20220222101244 failed during Execution. Error: "An exception occurred while executing a query: SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'user' already exists"
In ExceptionConverter.php line 47:
An exception occurred while executing a query: SQLSTATE[42S01]: Base table
or view already exists: 1050 Table 'user' already exists
I tried to remove schema update, this also lead into another error.
I also removed dropping database, then another error.
You create your schema twice:
First you do a doctrine:schema:update, that creates all tables like it is defined in your mapping.
Then you want to do the doctrine:migrations:migrate. I assume, that you have the CREATE TABLE definitions there, too. Thats why it complains.
If you remove this following line
php bin/console doctrine:schema:update --env=test --force || echo "No migrations found or schema update failed"
and have all setup in your migrations, it should work.
On command line I get connection and desired entities, no driver error here:
php bin/console dbal:run-sql 'select * from ourtest'
But on web i get error:
$this->connection->fetchAll('SELECT * FROM ourtest');
Handling
"App\Application\Command\DocumentUpload\DocumentUploadCommand" failed:
An exception occurred in driver: could not find driver
i tried
php -m display among others PDO, pdo_mysql, mysqli, mysqlnd
connection url from .env:
DATABASE_URL=mysql://xxx:xxx#mysql-db:3306/db_test_01?serverVersion=8.0
doctrine.yaml:
doctrine:
dbal:
dbname: db_test_01
host: mysql-db
port: 3306
user: xxx
password: xxx
driver: pdo_mysql
version: 8.0
My guess is the command line and your webserver use different configurations of PHP or different installations altogether.
Here's how to find out: Put a phpinfo() call in a file on your webserver (Do not do that on production as it will expose sensitive data to anyone with access to this file!). Open that file in your browser and check where your PHP installation is located.
On the command line, you can run which php to see where the PHP binary is located.
Compare the two and see whether you are running on the same binary. If it is indeed the same, then you should check which .ini file is used by the web server. In that .ini file you should find the name of the mysql extension (pdo_mysql.so) and it should not be commented out (no preceding ;).
I have a Symfony 4.1 app, where I use Doctrine and want to setup Redis cache for Doctrine.
Here is a part of composer.json
"snc/redis-bundle": "^2.1",
"symfony/doctrine-bridge": "^4.1",
"symfony/proxy-manager-bridge": "^4.1",
Here is yml config file:
snc_redis:
clients:
doctrine_cache:
type: phpredis
alias: doctrine_cache
dsn: '%my_dsn%'
doctrine:
metadata_cache:
client: doctrine_cache
entity_manager: default
The problem is: on the very first time when Symfony tries to generate cache for all DI containers, it initializes Redis connection. This means for example when I run any console command, it tries to connect to redis. Example:
// very first command after git clone and composer install
php bin/console about
Output:
In PhpredisClientFactory.php line 64:
php_network_getaddresses: getaddrinfo failed: No such host is known.
I expect that Redis cache service will be initialized lazily, otherwise I cannot run other build commands on independent (non having Redis) environment.
Can someone advise please?
If this happens after composer install then you might have composer run the default commands:
- "post-install-cmd"
- "post-update-cmd"
Try to remove them and add see if the Redis works... If it works then add a script to your deployment entrypoint to run them at the end.
PS: pay attention to doctrine and Redis if you are using migrations: then you should also clear doctrine cache.
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
I removed $hearAboutIndustry from the entity and now getting error below only in production server, not on local and staging server! Any idea why or solution?
Property Tete\AdminBundle\Entity\Customer::$hearAboutIndustry does not exist
500 Internal Server Error - ReflectionException
config_prod.yml
doctrine:
orm:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
What I have do to solve it so far:
Removed getter and setters from the entity.
Deleted whole cache and logs folders and re-created back, inc 777.
Just in case run cache:clear --env=prod
Searched hearAboutIndustry in all directories/files of the project. No reference at all.
Run doctrine:schema:update. DB is updated.
Run doctrine:generate:entities. Entity is updated.
app/console doctrine:cache:clear-metadata
app/console doctrine:cache:clear-query
app/console doctrine:cache:clear-result
As Adam suggested above in comment, we better restart apache if all the above solutions have been tried and getting no success. The solution is:
sudo apachectl graceful
php app/console doctrine:cache:clear-query --env=prod
Clearing ALL Query cache entries
php app/console doctrine:cache:clear-result --env=prod
Clearing ALL Result cache entries
php app/console doctrine:cache:clear-metadata --env=prod
Clearing ALL Metadata cache entries
php app/console cache:clear --env=prod
Clearing the cache for the prod environment with debug false
And don't forget to put --env=prod to your commands
"Old but still happens"
If none of the solutions mentioned above worked
try to delete the Entity cache file manually :
(e.g Entity costumer cache file path should be this one)
projectdirectory\projectname\var\cache{dev or prod}\jms_serializer\Tete-AdminBundle-Entity-Customer.cache.php
I had similar problem, I just used doctrine:mapping:import and that was it.
Cheers
We had the same issue and in our case (Nginx), the restart of Nginx didn't help.
But restart of memcache was the right solution:
sudo service memcached restart