Creare un database se non esiste con Spring Boot

di il
11 risposte

Creare un database se non esiste con Spring Boot

Ho una normalissima webapp scritta in Spring Boot che si collega ad un database di nome 'test'. Il file .properties è scritto in questo modo:
spring.datasource.url=jdbc:postgresql://127.1.1.1:5432/test
spring.datasource.username=postgres
spring.datasource.password=password
C'è modo di creare una webapp che crei questo 'test' qualora non esista?
Quale approccio dovrei seguire?
Come dovrei modificare la mia webapp?
grazie

11 Risposte

  • Re: Creare un database se non esiste con Spring Boot

    iBaffiPro ha scritto:


    C'è modo di creare una webapp che crei questo 'test' qualora non esista?
    Parto innanzitutto da una domanda: c'è un motivo molto ben specifico per cui il database non può essere creato prima?
    Spiego meglio: la creazione di un database richiede dei privilegi abbastanza elevati, che generalmente li ha solo la persona "amministratore" del DB che ha l'account con i grant per creare db. E questo account, detto sempre generalmente, NON ce l'ha l'applicazione, che invece ha un accesso al db tipicamente più "limitato" solo per l'uso basilare delle tabelle (select, insert, delete, update).
  • Re: Creare un database se non esiste con Spring Boot

    Al momento faccio tutto in locale ma mi sarebbe piaciuto far fare all'applicazione la creazione del dbms. In fase di produzione risparmio un passaggio.
  • Re: Creare un database se non esiste con Spring Boot

    La fase di 'bootstrap' di un'applicazione e' sempre una cosa complicata.

    La seguente logica NON DIPENDE da Spring/SpringBoot/...

    Diciamo che il 'database' DEVE esistere, non neccessariamente le tabelle.
    Quando la tua applicazione parte, controlla che ci siano tutte le tabelle. In pratica ne basta una.
    SE non c'i sono, allora le crei.

    Se usi un file di configurazione (ad esempio un XML)., puoi fare anche cose piu' complicate.
    Puoi AGGIUNGERE/CANCELLARE (CREATE/DROP) tabelle/colonne/indici/...

    Devi implementare a mano tali funzionalita' o sfruttare il supporto offerto da Hibernate/SpringData.

    CREATE DATABASE e' uno statement eseguito dall'amministratore, ma e' un po' limitativo che ua applicazione non abbia i diritti di CREATE/DROP TABLE/INDEX.


    per evitare conflitti con altre tabelle, una regola semplice e' usare nomi di tabelle/indici con un PREFISSO univoco (quindi NON 'tab', 'app', 'myapp', ...), che potrebbe essere configurabile
  • Re: Creare un database se non esiste con Spring Boot

    Ok, grazie, allora lascio così.
  • Re: Creare un database se non esiste con Spring Boot

    In effetti, se ho capito la questione, Spring Boot consente attraverso la definizione della proprietà spring.sql.init.platform=... in application.properties (dove ... può essere hsqldb, h2, oracle, mysql, postgresql) e i file schema-${platform}.sql e data-${platform}.sql di inizializzare 'automaticamente' il database. Tale funzionalità è, a mio avviso, utile soprattutto in fase di sviluppo con database che gira in memory quale H2, per avere un po' di dati coi quali fare test di integrazione e per vedere l'applicazione come va. La creazione e il popolamento del database, attraverso la proprietà spring.jpa.hibernate.ddl-auto, si può specificare avvenga una volta sola o ogni volta che si lancia l'applicazione (va da sé che si utilizza H2, in memoria, la creazione e l'eventuale popolamento dovrà avvenire a ogni lancio dell'applicazione).
    Un buon punto di inizio può essere la documentazione Spring Boot 2.5.4 paragrafo: 12.9.3. Initialize a Database Using Basic SQL Scripts.
    https://docs.spring.io/spring-boot/docs/2.5.4/reference/htmlsingle/#howto.data-initialization.using-basic-sql-scripts.

    P.S.:
    Se non ricordo male, fino a non molte versioni fa di Spring Boot, anziché la proprietà: spring.sql.init.platform si utilizzava la proprietà: spring.datasource. ... (comunque tutto da controllare)
  • Re: Creare un database se non esiste con Spring Boot

    Io in locale uso PostgreSQL e ho sia lo schema che i dati del DB. I file .sql che uso in locale li uso anche in produzione perché Spring Boot aggiunge dati e tabelle solo se non esistono già. Quando metto la webapp sul server non vado a creare tabelle o a lanciare query. Oltre allo schema e ai dati mi sarebbe anche piaciuto creare il database. Ho provato ad aggiungere allo schema questo codice:
    
    CREATE DATABASE test
        WITH
        OWNER = postgres
        ENCODING = 'UTF8'
        CONNECTION LIMIT = -1;
    
    ma non funziona perché spring.datasource.url deve già puntare ad un DB esistente. Andbin parla di privilegi diversi per creare database e per creare le tabelle ma in locale io ho un solo account per fare tutto e farò allo stesso modo anche in produzione, per me questo non sarebbe un problema. La mia webapp ha 2 properties, uno parte in locale e l'altro solo in produzione e contiene la user e la password dell'utente con più privilegi del DB. Mi sarebbe piaciuto far creare alla webapp anche il database ma credo che Spring Boot non contempli questa possibilità.
    Grazie mille per i vostri interventi
  • Re: Creare un database se non esiste con Spring Boot

    P.S.: Ho anche provato questo codice ma sembra funzionare solo con MySQL:
    spring.datasource.url=jdbc:postgresql://127.1.1.1:5432/nomedatabase?createDatabaseIfNotExist=true
    ma non funziona. Al momento uso Spring Boot 2.5.2 ma a breve aggiorno a 2.5.4.
  • Re: Creare un database se non esiste con Spring Boot

    iBaffiPro ha scritto:


    spring.datasource.url deve già puntare ad un DB esistente
    non mi risulta, può anche essere usato per creare un db, ad esempio per ricrearlo e ripopolarlo quando si eseguono test di integrazione che lo modificano (attraverso l'annotazione @Sql).
    Il punto importante comunque è che creare e ripopolare un db, dipende dal contenuto degli script schema e data. Spring Boot ha 'solo' il compito di eseguirli.
    Mi sarebbe piaciuto far creare alla webapp anche il database ma credo che Spring Boot non contempli questa possibilità.
    E' possibile creare un db con le relative tabelle e popolarlo anche con script già esistenti. Occorre modificare le impostazioni di default con spring.sql.init.schema-locations=... e spring.sql.init.data-locations=...
  • Re: Creare un database se non esiste con Spring Boot

    iBaffiPro ha scritto:


    P.S.: Ho anche provato questo codice ma sembra funzionare solo con MySQL
    I parametri nel url JDBC non sono "universali" .... ma dipendono fortemente dal DBMS e soprattutto dal suo driver JDBC.

    I parametri per Postgresql sono documentati qui: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters

    Non c'è traccia di un createDatabaseIfNotExist

    Per il Connector/J di MySQL invece sì, esiste.
  • Re: Creare un database se non esiste con Spring Boot

    paolo.bertin ha scritto:


    iBaffiPro ha scritto:


    spring.datasource.url deve già puntare ad un DB esistente
    non mi risulta, può anche essere usato per creare un db, ad esempio per ricrearlo e ripopolarlo quando si eseguono test di integrazione che lo modificano (attraverso l'annotazione @Sql).
    Il punto importante comunque è che creare e ripopolare un db, dipende dal contenuto degli script schema e data. Spring Boot ha 'solo' il compito di eseguirli.
    Mi sarebbe piaciuto far creare alla webapp anche il database ma credo che Spring Boot non contempli questa possibilità.
    E' possibile creare un db con le relative tabelle e popolarlo anche con script già esistenti. Occorre modificare le impostazioni di default con spring.sql.init.schema-locations=... e spring.sql.init.data-locations=...
    Si uso spring.sql.init.schema-locations nel mio progetto ma se nei file .sql aggiungo il codice per creare il database che ho scritto sopra non vado da nessuna parte. Tu hai provato su uno dei tuoi progetti? Ti risulta possibile? Usi PostgreSQL?
  • Re: Creare un database se non esiste con Spring Boot

    andbin ha scritto:


    iBaffiPro ha scritto:


    P.S.: Ho anche provato questo codice ma sembra funzionare solo con MySQL
    I parametri nel url JDBC non sono "universali" .... ma dipendono fortemente dal DBMS e soprattutto dal suo driver JDBC.

    I parametri per Postgresql sono documentati qui: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters

    Non c'è traccia di un createDatabaseIfNotExist

    Per il Connector/J di MySQL invece sì, esiste.
    Concordi con me che con PostgreSQL questa operazione non è fattibile?
    Che peccato però... -1 a PostgreSQL e +1 a MySQL!
    Tu non hai proprio nessuna idea di come potrei aggirare il problema?
    Io ho 1 solo user in PostgreSQL che può fare tutto, creare e cancellare DB, tabelle, ecc...
Devi accedere o registrarti per scrivere nel forum
11 risposte