Generere Symfony2 inventar fra DB?

stemmer
32

Er det mulig å generere inventar fra en eksisterende DB i Symfony2 / Lære? Hvordan kunne jeg gjøre det?

Eksempel:

Jeg har definert 15 enheter og min symfony2 program fungerer. Nå noen mennesker er i stand til å bla til programmet og ved å bruke det den hadde satt rundt 5000 rader før nå. Nå ønsker jeg den innsatte som inventar ting, men jeg ønsker ikke å gjøre dette for hånd. Hvordan kan jeg generere dem fra DB?

Publisert på 11/06/2011 klokken 20:33
kilden bruker
På andre språk...                            


7 svar

stemmer
8

Det er ingen direkte måte innenfor Lære eller Symfony2, men å skrive en kodegenerator for det (enten innenfor eller utenfor SF2) ville være trivielt. Bare trekk hver eiendom og generere en linje med kode for å sette hver eiendom, og deretter sette den i ligaen ileggingsmetode. Eksempel:

<?php
$i = 0;
$entities = $em->getRepository('MyApp:Entity')->findAll();
foreach($entities as $entity)
{
   $code .= "$entity_{$i} = new MyApp\Entity();\n";
   $code .= "$entity_{$i}->setMyProperty('" . addslashes($entity->getMyProperty()); . "'); \n");
   $code .= "$manager->persist($entity_{$i}); \n $manager->flush();";
   ++$i;
}
// store code somewhere with file_put_contents
Svarte 24/06/2012 kl. 01:25
kilden bruker

stemmer
4

Som jeg forstår spørsmålet ditt, har du to databaser: den første er allerede i produksjon og fylt med 5000 rekker, er den andre en ny database du vil bruke for ny test og utvikling. Er det riktig ?

Hvis det er, foreslår jeg at du oppretter i deg testmiljø to enhet manager: den første vil være 'standard' en, som vil bli brukt i prosjektet (dine kontrollere, etc.). Den andre skal brukes til å koble til produksjonsdatabasen. Du finner her hvordan man skal håndtere flere foretaket manager: http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html

Deretter bør du lage et innslag klasse som vil ha tilgang til din container. Det er en "how to" her: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures .

Ved hjelp av beholderen, vil du ha tilgang til både enhet manager. Og dette er den 'magiske': du er nødt til å hente objektet fra produksjon database, og vedvarer dem i andre foretak manager, som vil sette dem i testdatabase.

Jeg peker oppmerksomheten til to punkter:

  • Hvis det er forholdet mellom objekt, må du ta vare på disse avhengigheter: eiersiden, inversed side, ...
  • Hvis du har 5000 rader, ta vare på minne skriptet vil bruke. En annen løsning kan være å bruke mors sql for å hente alle radene fra produksjon database og sett dem i testdatabase. Eller en SQL-skript ...

Jeg har ikke noen kode for å foreslå for deg, men jeg håper denne ideen vil hjelpe deg.

Svarte 30/08/2012 kl. 09:06
kilden bruker

stemmer
3

Jeg antar at du vil bruke inventar (og ikke bare dumpe produksjon eller iscenesettelsen databasen i utviklingen database) fordi a) dine skjemaendringer og dumper ikke ville fungere hvis du oppdaterer koden din eller b) du ikke ønsker å dumpe hullet databasen, men bare ønsker å utvide noen tilpassede inventar. Et eksempel jeg kan tenke på er: du har 206 land i din iscenesettelse database og brukere legge til steder de landene; å holde inventar liten at du bare har 5 land i din utvikling database, men du vil legge til de byene som brukeren har lagt til de 5 landene i iscenesettelsen databasen til utvikling database

Den eneste løsningen jeg kan tenke på er å bruke nevnte DoctrineFixturesBundle og flere foretakets ledere.

Først av alt bør du konfigurere to databasetilkoblinger og to foretakets ledere i din config.yml

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   %database_driver%
                host:     %database_host%
                port:     %database_port%
                dbname:   %database_name%
                user:     %database_user%
                password: %database_password%
                charset:  UTF8
            staging:
                ...

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        default_entity_manager:   default
        entity_managers:
            default:
                connection:       default
                mappings:
                    AcmeDemoBundle: ~
            staging:
                connection:       staging
                mappings:
                    AcmeDemoBundle: ~

Som du kan se begge foretakets ledere kartlegge AcmeDemoBundle (i denne pakken vil jeg sette inn koden for å laste inventar). Hvis den andre databasen er ikke på utviklingsmaskinen, kan du bare dumpe SQL fra den andre maskinen til utvikling maskinen. Det burde være mulig siden vi snakker om 500 rader og ikke om millioner av rader.

Hva du kan gjøre videre er å implementere et innslag laster som bruker tjenesten container for å hente den andre enheten leder og bruker Lære å spørre data fra andre database og lagre den på din utvikling database (den defaultenhet manager):

<?php

namespace Acme\DemoBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Acme\DemoBundle\Entity\City;
use Acme\DemoBundle\Entity\Country;

class LoadData implements FixtureInterface, ContainerAwareInterface
{
    private $container;
    private $stagingManager;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
        $this->stagingManager = $this->container->get('doctrine')->getManager('staging');
    }

    public function load(ObjectManager $manager)
    {
        $this->loadCountry($manager, 'Austria');
        $this->loadCountry($manager, 'Germany');
        $this->loadCountry($manager, 'France');
        $this->loadCountry($manager, 'Spain');
        $this->loadCountry($manager, 'Great Britain');
        $manager->flush();
    }

    protected function loadCountry(ObjectManager $manager, $countryName)
    {
        $country = new Country($countryName);
        $cities = $this->stagingManager->createQueryBuilder()
            ->select('c')
            ->from('AcmeDemoBundle:City', 'c')
            ->leftJoin('c.country', 'co')
            ->where('co.name = :country')
            ->setParameter('country', $countryName)
            ->getQuery()
            ->getResult();
        foreach ($cities as $city) {
            $city->setCountry($country);
            $manager->persist($city);
        }
        $manager->persist($country);
    }
}

Det jeg gjorde i loadCountrymetoden var at jeg laster objektene fra stagingforetaket manager, legge en referanse til ligaen landet (den som allerede finnes i din nåværende inventar) og vedvarer det ved hjelp av defaultforetaket manager (din utvikling database).

kilder:

Svarte 12/09/2012 kl. 22:22
kilden bruker

stemmer
0

du kan bruke https://github.com/Webonaute/DoctrineFixturesGeneratorBundle Det legger evne til å generere kamper for enkelt enhet ved hjelp av kommandoer som

$ php bin/console doctrine:generate:fixture --entity=Blog:BlogPost --ids="12 534 124" --name="bug43" --order="1"

Eller du kan opprette fulle snapshot

php app/console doctrine:generate:fixture --snapshot --overwrite
Svarte 05/04/2017 kl. 21:11
kilden bruker

stemmer
0

Den AliceBundle kan hjelpe deg å gjøre dette. Faktisk gjør det mulig å laste inventar med YAML (eller PHP array) filer.

For eksempel kan du definere dine inventar med:

Nelmio\Entity\Group:
    group1:
        name: Admins
        owner: '@user1->id'

Eller med den samme struktur i et PHP-array. Det er måten enklere enn å generere arbeids PHP-kode.

Den støtter også referanser:

Nelmio\Entity\User:
    # ...

Nelmio\Entity\Group:
    group1:
        name: Admins
        owner: '@user1'
Svarte 10/05/2016 kl. 12:46
kilden bruker

stemmer
0

Lære Inventar er nyttige fordi de tillater deg å opprette objekter og sette dem inn i databasen. Dette er spesielt nyttig når du trenger å skape assosiasjoner eller si, kode et passord ved å bruke en av de passord kodere. Hvis du allerede har data i en database, bør du egentlig ikke trenger å ta dem ut av det formatet og slå den inn i PHP-kode, bare for å ha det PHP-koden inn de samme dataene tilbake inn i databasen. Du kan sannsynligvis bare gjøre en SQL-dump og deretter sette dem inn i databasen igjen på den måten.

Ved hjelp av et innslag ville være mer fornuftig hvis du var å initiere prosjektet, men ønsket å bruke brukerundersøkelser for å lage den. Hvis du hadde i config-filen standard brukernavn, kan du lese det og sette inn objektet.

Svarte 07/06/2012 kl. 20:17
kilden bruker

stemmer
-2

I doctrine_fixture kokebok, kan du se i det siste eksempelet hvordan å få tjenesten container i din enhet.

Med denne tjenesten container, kan du hente læren service, så foretaket manager. Med foretaket manager, vil du være i stand til å få alle data fra databasen du trenger.

Håper dette vil hjelpe deg!

Svarte 14/06/2011 kl. 17:32
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more