How to Setup Table Prefix in Symfony2

How to setup table prefix in symfony2

Having just figured this out myself, I'd like to shed some light on exactly how to accomplish this.

Symfony 2 & Doctrine 2.1
Note: I use YML for config, so that's what I'll be showing.

Instructions

  1. Open up your bundle's Resources/config/services.yml

  2. Define a table prefix parameter:

    Be sure to change mybundle and myprefix_

    parameters:
    mybundle.db.table_prefix: myprefix_
  3. Add a new service:

    services:
    mybundle.tblprefix_subscriber:
    class: MyBundle\Subscriber\TablePrefixSubscriber
    arguments: [%mybundle.db.table_prefix%]
    tags:
    - { name: doctrine.event_subscriber }
  4. Create MyBundle\Subscriber\TablePrefixSubscriber.php

    <?php
    namespace MyBundle\Subscriber;

    use Doctrine\ORM\Event\LoadClassMetadataEventArgs;

    class TablePrefixSubscriber implements \Doctrine\Common\EventSubscriber
    {
    protected $prefix = '';

    public function __construct($prefix)
    {
    $this->prefix = (string) $prefix;
    }

    public function getSubscribedEvents()
    {
    return array('loadClassMetadata');
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $args)
    {
    $classMetadata = $args->getClassMetadata();
    if ($classMetadata->isInheritanceTypeSingleTable() && !$classMetadata->isRootEntity()) {
    // if we are in an inheritance hierarchy, only apply this once
    return;
    }

    $classMetadata->setTableName($this->prefix . $classMetadata->getTableName());

    foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
    if ($mapping['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY
    && array_key_exists('name', $classMetadata->associationMappings[$fieldName]['joinTable']) ) { // Check if "joinTable" exists, it can be null if this field is the reverse side of a ManyToMany relationship
    $mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name'];
    $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
    }
    }
    }
    }
  5. Optional step for postgres users: do something similary for sequences

  6. Enjoy

How to programmatically change table prefix in symfony2-doctrine

In order to change the table you've got to to update Doctrine's class meta data of that entity.

// getEntityManager() = $this->getDoctrine()->getManager()
$articleMetaData = $this->getEntityManager()->getMetadataFactory()->getMetadataFor(Article::class);
$metaDataBuilder = new ClassMetadataBuilder($articleMetaData);
$metaDataBuilder->setTable('db2_article');
$this->getEntityManager()->getMetadataFactory()
->setMetadataFor(Article::class, $metaDataBuilder->getClassMetadata());

$article2MetaData = $this->getEntityManager()->getClassMetadata(Article::class);
$article2MetaData->getTableName(); // is now db2_article
$this->getEntityManager()->find(Article::class, 1); // will query db2_article ID -> 1

To see what the class meta data is up to as in methods, see: Doctrine PHP Mapping

How to add a prefix to migrated tables in Symfony 5

I followed the guide from @Dlk, had to amend the getPrefix() func for my directory layout, after that all's good, thank you both for the help. :) Hopefully this'll help out another newbie in future!

Having different table prefixes in separate Symfony2 Bundles

The problem seems to be that both prefixes share the same parameter key, with the second occurence overwriting the first.
I guess you must use two keys, like MYBUNDLE.db.table_prefix_oauth and MYBUNDLE.db.table_prefix_api.

add prefix in table name without change in annotation of Doctrine

You can add a table prefix by using Doctrines event manager as described in the Doctrine documentation here:

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/cookbook/sql-table-prefixes.html

In a previous question, simshaun has given a good example of how to implement this in symphony:

How to setup table prefix in symfony2

Symfony Doctrine (Migration) with prefix

Okay I think I found the solution for the migration:
Keyword: ContainerAwareInterface

You can implement the ContainerAwareInterface to your migration class and just access all parameters and services you have implemented. Great thing!

Here is an example:

<?php

namespace FooBla\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class Version20160810121166 extends AbstractMigration implements ContainerAwareInterface
{
private $container;

public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}

/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$em = $this->container->getParameter('database_prefix'); //Just use the parameter directly in the migration calls
$this->addSql('CREATE TABLE `'.$em.'sessions` (`sess_id` VARBINARY(128) NOT NULL PRIMARY KEY, `sess_data` BLOB NOT NULL, `sess_time` INTEGER UNSIGNED NOT NULL, `sess_lifetime` MEDIUMINT NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB');
}

/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
}
}


Related Topics



Leave a reply



Submit