Using django south with a different set of database credentials - django

I'm building a Django app which connects to a PostgreSQL database, and the credentials that the app uses has quite limited permissions granted over the relevant tables.
I'd like to be able to use south to manage database migrations, but given that this picks up on the same credentials that Django uses, this throws an error as south cannot make any changes to tables it doesn't own.
Is there a way to specify that south should use a different set of credentials to manage migrations other than that specified by the application settings?

Yes : have another set of settings with different credentials for south migrations and use the --settings option when calling the migrate command.
NB : to avoid DRY violation, you can as well start your special settings file by importing * from the normal settings and just override the DB credentials.

Related

Django transfer database to different Django project without messing up the logic

I built a Django project with a few models. Now I created a second server with the same setup. This one is meant to be the deployment server. Databases are separate from the dev-server.
However can you tell me if I can simply copy the databases from the dev server to the deploy or will the Django logic, since I also mean the user models and permissions etc.
The tables which I created myself are no problem to transfer to the new server. However I am wondering If Django gets confused when I also transfer something like the auth_user Model.
Should this work since I also just copied the backend logic as well?

How to load django app models in a project without this project taking responsibility for migrations

Given the following architecture of django projects apps and database schemas:
There is a django app which I want to share between several django projects.
Each project has it's own postgresql schema in behind. All schemas live in the same postgresql database.
One project is owner of the apps data, this project is responsible to run migrations and the data should live in its schema.
All other projects may access the data from the other projects schema, because they have a proper postgresql search path set.
We already use this concept with an app that has all models set to unmanaged, which works. But database changes always needs to be done manually. I'd like to benefit from django migrations and therefore I want my models either managed or unmanaged.
Do you think app config is good place to change the models meta? Any other suggestions and approaches on how to solve the requirement are also welcome.
The in the comments mentioned setting MIGRATION_MODULES works very well. In those projects which should only access the data and which should not be responsible for the migrations you can easily disable the migrations like that:
MIGRATION_MODULES = {
'yoursharedapp': None
}
Note that you need to configure the postgresql role used in the those projects with proper grants and search path.

"Django documentation" says "ensure that Django has permission to create and alter tables" so how do I do that in postgreSQL?

I'm taking EdX classes that use Ruby on Rails and python. That has given me courage to try and install and learn Django using Apach, mod_wsgi, and PostgreSQL. Following the detailed installation instructions, I first installed Apache, then mod_wsgi, and then PostgreSQL. I installed each from source and went through a little bit of tutorial with each and made sure they were properly installed. I've got a postgres user setup to run the PostgreSQL server and I was able to create a user "role" for myself as well as an admin role that my role inherits from that can create a database etc. I tried out some SQL in psql following a tutorial to make tables etc. I know how to grant privileges for a given role.
So anyway, I'm pretty close to the step where I would actually install Django from source, but I'm not sure how to follow this advice from the installation instructions:
If you plan to use Django's manage.py syncdb command to automatically create database tables for your models, you'll need to ensure that Django has permission to create and alter tables in the database you're using; if you plan to manually create the tables, you can simply grant Django SELECT, INSERT, UPDATE and DELETE permissions.
Maybe after I follow the steps to actually install Django and go through some tutorials, I'll understand exactly what needs to be setup in PostgreSQL to grant Django those permissions, but if I follow the installation instructions in order, it would seem to be saying I should setup those permissions now before installing Django. If I can get someone to tell me how to do it here before I do the install of Django, I'd appreciate it.
In the settings.py file of a django project, there is a snippet that says something like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproj_db',
'USER': 'myproj_user',
'PASSWORD': '123',
'HOST': '',
'PORT': '',
},
}
What this does is that it tells Django what user (postgres user in this case) and database is used in conjunction with your django project.
Normally, you will need to create this myproj_user together with the myproj_db.
When you create this user, you can choose to give it permissions like so:
CREATE USER myproj_user WITH PASSWORD '123' SUPERUSER CREATEDB CREATEROLE LOGIN;
This creates the myproj_user with superuser, createdbm createrole, login permissions allowed to the user.
And then the database like so:
CREATE DATABASE myproj_db WITH OWNER myproj_user TEMPLATE=template1 ENCODING='utf-8';
You say that you know how to grant privileges for a given role, which is what you need to do for Django before installing it (running syncdb).
This is part of setting up your database for use with Django – a step you take before creating each Django project. Each Django project corresponds to a site that you build with Django and is completely separate from another Django project. To each project belongs a database.* You can install Django the framework before you setup your database, because Django the framework doesn't do anything on its own.
Either you give Django permissions to create tables for you, in which case it can create tables for you (using manage.py syncdb). Or, you use manage.py sqlall <app> to get SQL that you run yourself to create the tables needed (which might be nice if you're paranoid about security).
To grant all permissions to a user for a specific database (option 1) in Postgres, use the command (from psql):
GRANT ALL PRIVILEGES ON DATABASE <db-name> TO <username>;
* Technically, they can share a database by simply configuring them to use the same one.
Django uses ORM (Object Relational Mapper). What that means is that you do not directly deal with database tables for querying things however you deal with certain classes which then deal with the database. This is very useful and much more user-friendly then doing manually SQL. Consider the following example:
SELECT * FROM foo WHERE field="value"
vs
Foo.objects.filter(field='value')
In ORM, you describe the tables you have by making certain classes (in Django we call them models) and those models correspond to tables in the db, and their fields correspond to the columns in the db table. The following are very similar:
CREATE TABLE foo (
title varchar(50),
description text,
likes integer
);
and
class Foo(models.Model):
title = models.CharField(max_length=50)
description = models.TextField()
likes = models.IntegerField()
However it is waste of time for you as a developer to construct the SQL statements for creating tables, and describing those tables in Python as models. Not to do that, Django allows you once you define all your models, to create db tables for you. That is the purpose of the syncdb command. It takes all the installed apps and models within them and creates tables within your database for them. However as you already mentioned in your question, databases have roles and those roles have permissions. For example, one of the permissions is CREATE as described here. So what Django documentation is saying is for you to grand all necessary permission to a role which Django will use to interact with the db for Django to be able to create necessary db tables it needs as well as possibly modify them later.

Migrate user groups and permissions in Django?

I've built an application that I want to move from my development server to my production server. In this application I have defined 3 custom groups in auth.group and each of those have specific permissions.
I've tried to dump the data from auth.group - it seems to include permissions ids as well. The problem is, those IDs don't match between my development environment and the production environment. It also seems there is a content_type_id in auth.permission that I don't know how it relates.
My question is, is there a way using dumpdata or something else, to migrate Groups and all of the related permissions for my application? I don't have a problem importing multiple fixtures on the production server, but I do want all of the groups to be set up without having to go through the UI and selecting the appropriate permissions for each group.
django.contrib.auth depends on django.contrib.contenttypes because auth.models.Permission.content_type is a ForeignKey(ContentType).
Solution: add ContentType in your data dump, ie. dumpdata with the following arguments: auth.group contenttypes.contenttype auth.permission

What is the best approach for migrating one Django app to another

I am working on a Django project where I have to use South to migrate one application to another. I have the old internal message application which I have to replace by another completely different. I was wondering if I could pass by orm, but the old application doesn't exist anymore in the INSTALLED_APPS, so no sense. Does using a SQL procedure is the way to do that? I'd like to keep the application DB type independant at the time.
Django applications are namespaced in the database so you ought to be able to temporarily have both applications installed. I would break it down to about three migrations:
A schemamigration to add the new application. If other applications need to have foreign key relations to the new application, add those and just make sure they are all nullable.
A datamigration to walk the model objects in the old application and create the equivalent ones in the new application.
A schemamigration to remove the old application.
schemamigration: python manage.py schemamigration myapp (with nullable foreign keys)
datamigration: Django custom sql is my friend -> https://docs.djangoproject.com/en/dev/topics/db/sql/
have made my custom data migration script keeping the project DB independent
remove the old application schema using 2.
(optional) a backwards rescue script