How to update the database in Symfony 4? - database

When I give the following command:
php bin/console doctrine:schema:update --force
the database gets updated, but afterwards this command:
php bin/console doctrine:schema:validate
keeps saying that the database is not in sync (see below screenshot).
What am I missing/doing wrong?

Depending on the database type and OS, the test may give some "false negatives", which means that your db is already ok but Doctrine doesn't quite understand. It happened to me in several projects, regardless of Symfony version (which means, Symfony 2,3 and 4).
Besides, in Symfony 4 you can use migrations as explained in the docs, that is:
bin/console make:migration
this command will create a migration file inside src/Migrations, but won't touch the db.
To understand what's going on (from Doctrine's oint of view) you may have a look at the migration file: it's a PHP class with two methods (up() and down()).
The up() method will contain the query/queries needed to align the database with your mapping files.
To apply all the pending migrations, run:
bin/console doctrine:migrations:migrate

Related

Postgresql changes in Heroku and Django combo with shared database

I've just started using Heroku with Django and it seems great. However, when I change my existing models I'm not sure how to run those changes to the Heroku environment. The syncdb works just fine when adding all new database tables, but how should I modify existing tables?
I found out that Heroku provides psql access only to a dedicated database so that's out of the question. I haven't tried South but it seems like a solution.
So I guess I'm asking how to make database changes with Django and Heroku?
What you are asking for is called "schema migration" or even "schema evolution". Django has some documentation about it on the wiki.
Django's syncdb command does not support that. As a matter of fact, the documentation for syncdb is clear:
Creates the database tables for all apps in INSTALLED_APPS whose
tables have not already been created
Rather, django proposes to use drop the tables manually and then to run syncdb again in the documentation of the deprecated reset command:
You can also use ALTER TABLE or DROP TABLE statements manually.
But fear not, there are many reusable apps to help you with proper schema migrations and hopefully you can pick the one that suits you best. Rather than elaborate in my answer, please let me link an article I wrote about Django schema migration which compares all current solutions.
South works great on Heroku.

Prevent syncdb from updating database in Django?

I'd like to respect the database as a "read-only" and never write to it. Is there a way to easily prevent syncdb from even bothering to check to update the database?
With Django 1.2 and the ability to have multiple databases, it'd like to be able to query a database for information. I'd never need to actually write to that database.
However, I'd be scared if syncdb ran and attempted to update that database (because I may not have a technically read-only account to that database). Mainly, I'd just like to use/abuse the Django ORM as a way to query that database.
UPDATE: Sorry, I need to be able to sync one of the databases in settings.py, just not this specific one.
Heh, I guess I'll answer my own question (RTFM!)...
http://docs.djangoproject.com/en/dev/topics/db/multi-db/#an-example
def allow_syncdb(self, db, model):
...
That's a definite start...
If you don't need syncdb, don't run it, simple as that. Updating the database is what it does, so if you don't need that, you shouldn't run it - it doesn't do anything else.
However if you're actually asking how to prevent syncdb from running at all, one possibility would be to define a 'dummy' syncdb command inside one of your apps. Follow the custom management command instructions but just put pass inside the command's handle method. Django will always find your version of the command first, making it a no-op.
This issue came up for me when working with read-only mirrors of Microsof SQL Server databases (uhhg). Since you can't selectively run syncdb on a single app or database. But you have to run syncdb when you first create a new Django project or install an new app that requires it (like south). What I did was to put my read-only database in its own Django app and then add an empty South migration to that app. That way syncdb thinks south is handling db setup for those apps, and south doesn't do anything to them!
manage.py schemamigration ap_with_read_only_database --empty initial_empty_migration_that_does_nothing
That leaves you free to manage the schema of that db outside of django.

How to actually use liquibase in a maven project with svn

Last week i read about liquibase quick start and all the related tutorials but i feel like i don't get the whole drift about using it for consecutive change in the database and i have some questions still opened.
i'm developing an application in netbeans using maven with 3 modules: dbunit module, service module and the webapp module.As you might have guessed dbunit does the database stuffs, the service is on top of it and the webapp uses the services.so the parent pom has the declaration of all groupids, artifactids and versions for all jars and plugins.
I manage to generate the changelog file from command line since the db is already existing and supposing i set up everything correctly using liquibase maven plugin :
question 1 : What will the liquibase goal be since right now i'm doing any database change right now?
Question 2 : If i want to add for example a new table to the database, will i add the this new changeSet to the same changelog file or i have to create a new changelog.xml file?
Question 3 : I believe when the dbunit runs it will run the changeset but is that necessary to add the plugin to th webapp module too (maybe to run the liquibase goal before deployment with cargo plugin) or the dbunit will take care of that?
Question 4 : What exactly subversion helps with keep the states of the changelog (assuming there is only one changelog refere to question 2)
thanks for reading this and for you help.
See http://www.liquibase.org/documentation/maven
so you should bind your liquibase execution to a phase like
<phase>process-resources</phase>
But i use a spring executor, too. So everytime my app starts up, it starts a liquibase executor to execute missing changelogs in the database. It is nice, because when you are ready with your work and your tests, liquibase has updated your dev database but not your production database. But when you install your war and start your webapp, liquibase handles it automatically to bring your database to current state. So you don't have to remember doing some extra stuff before deploying your new version.
Keep your changelog.xml with includes to changelog files like this
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
when you want a new table, add a changelog-0002.xml file and reference it in your master changelog.xml
see answer 1. I would put in your webapp module too.
You should have many changelog files. so this question is not applicable.

Is it possible to generate django models from the database?

I've been messing around with Django and the Django ORM at home, and I've got to say, I feel it is one of the best out there in terms of ease of use.
However, I was wondering if it was possible to use it in "reverse".
Basically what I would like to do is generate Django models from an existing database schema (from a project that doesn't use django and is pretty old).
Is this possible?
Update: the database in question is Oracle
Yes, use the inspectdb command:
http://docs.djangoproject.com/en/dev/ref/django-admin/#inspectdb
inspectdb
Introspects the database tables in the database pointed-to by the DATABASE_NAME setting and outputs a Django model module (a models.py file) to standard output.
Use this if you have a legacy database with which you'd like to use Django. The script will inspect the database and create a model for each table within it.
As you might expect, the created models will have an attribute for every field in the table. Note that inspectdb has a few special cases in its field-name output:
[...]
(Django 1.7.1) Simply running python manage.py inspectdb will create classes for all tables in database and display on console.
$ python manage.py inspectdb
Save this as a file by using standard Unix output redirection:
$ python manage.py inspectdb > models.py
(This works for me with mysql and django 1.9)
I have made a reusable app based on django's inspectdb command utility,
Django Inspectdb Refactor.
This breaks models into different files inside models folder from a existing database.
This helps managing models when they become large in number.
You can install it via pip:
pip install django-inspectdb-refactor
Then register the app in settings.py as inspectdb_refactor
After this you can use it from command line as :
python manage.py inspectdb_refactor --database=your_dbname_defined_in_settings --app=your_app_label
This will successfully create models folder with all the tables as different model files inside your app. For example:
More details can be found here.

Zend Framework: Getting started using SQLite

Sorry if this is overly simplistic.
I've decided that I want to use an SQLite database instead of a MySQL database. I'm trying to wrap my head around how simple SQLite is and would like a simple, one answer tutorial on how to use SQLite with the Zend Framework, where to put my SQLite database in my directory structure, how to create the database, etc.
#tuinstoel is correct, attaching to an SQLite database implicitly creates it if it does not exist.
SQLite also supports a command-line client that is more or less like MySQL's command shell, allowing you to issue ad hoc commands or run SQL scripts. See documentation here: http://www.sqlite.org/sqlite.html
Of course you need to change the Zend_Db adapter in your ZF application. ZF supports only an adapter to the PDO SQLite extension. SQLite doesn't support user/password credentials. Also since SQLite is an embedded database instead of client/server, the "host" parameter is meaningless.
$db = Zend_Db::factory("pdo_sqlite", array("dbname"=>"/path/to/mydatabase.db"));
One more caveat: when you get query results in associative-array format, some versions of SQLite insist on using "tablename.columnname" as the keys in the array, whereas other brands of database return keys as simply "columnname". There's an outstanding bug in ZF about this, to try to compensate and make SQLite behave consistently with the other adapters, but the bug is unresolved.
If you make a connection to a not existing database, a database is created on the fly. (You can turn this behavour off)
This is now covered in the Zend Framework quickstart tutorial (version 1.9.5 as of this writing). Just make a new project (with zf command line tool. look here for a great tutorial on setting it up), add these lines to your config.ini file and you're good to go:
; application/configs/application.ini
[production]
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/databaseName.db"
Now when you ask for your default database adapter, it will use this one. I would also recommend downloading the quickstart tutorial source code and making use of the load.sqlite.php script. You can create a schema and data file and load the database with these tables/columns/values. It's very helpful! Just check out the tutorial. It's all in there.
This answer was moved out of the question into a CW answer to disavow ownership over the content.

Resources