I need to make two separate Django projects share the same database. In project_1 I have models creating objects that I need to use in project_2 (mostly images).
The tree structure of project_1_2 is:
project_1/
manage.py
settings.py
project_1_app1/
...
...
project_2/
manage.py
settings.py
project_2_app1/
...
...
Which is the best approach?
EDIT: I'm using sqlite3 in my development environment.
I'd like to keep my two django projects as stand-alone projects (so that both can be upgraded safely from their respective repositories).
# in project_1/settings.py
import os
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
..
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_ROOT, 'development.db'),
},
}
...
# in project_2/settings.py
import os
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
..
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_ROOT, 'development.db'),
},
}
...
In this way, each project has its own development.db (the one that I need to be shared):
project_1/development.db
project_2/development.db
but I guess I need to do something more to make it shared (and unique).
The best for me would be to keep the development.db at project_1/ path and thus set the project_2/settings.py DATABASES to point to project_1/development.db.
You can simply define the same database in DATABASES in your settings.py. So, if your database is PostgreSQL, you could do something like this:
# in project_1/settings.py
DATABASES = {
'default': {
'NAME': 'common_db',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'project_1_user',
'PASSWORD': 'strong_password_1'
},
}
# in project_2/settings.py
DATABASES = {
'default': {
'NAME': 'common_db',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'project_2_user',
'PASSWORD': 'strong_password_2'
},
}
Note that both database users (project_1_user and project_2_user) should have the appropriate privileges on the database you wish to use. Or you could instead use the same user for both projects.
If you want to have more than just one database per project, you should take a look at the docs for multiple databases.
On another matter, since you share data, I guess you share functionalities as well. So for example, if project_1_app1 and project_2_app1 do same (or similar) things, it seems they could instead be a single reusable app.
Edit
Since you use sqlite3, you should ensure the path you use is the same. So, assuming that project_1 and project_2 are siblings, like so:
projects
project_1
settings.py
...
project_2
settings.py
...
you should try this:
# project_1/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_ROOT, 'development.db'),
},
}
# project_2/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(
os.path.dirname(os.path.dirname(PROJECT_ROOT)),
'project_1',
'development.db'
),
},
}
This would give the structure you ask for. Note however that the projects are not both "standalone". project_2 is clearly dependent on project_1's database.
In any case, perhaps, you should also take a look at the os.path module for more info.
You just need to declare in your model in class meta the attribute db_table with a name diferent the name of app + model (Which are automatically generated by Django) the twice projects need the same models. before the run makemigrations and migrate.
class MyModel(models.Model):
class Meta:
db_table = 'MyModel'
Related
Question:
How can I add multiple databases for testing in Django?
When I ran my test suits I got this Error:
AssertionError: Database queries to 'mig' are not allowed in this test. Add 'mig' to path_to_test_suit.MigrationServiceTest.databases to ensure proper test isolation and silence this failure.
Here are my PostgreSQL settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'db_1_name',
'USER': 'db_1_user',
'PASSWORD': 'db_1_passwd',
'HOST': 'db_1_host',
'PORT': 'db_1_port',
},
'mig': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': db_2_name,
'USER': db_2_user,
'PASSWORD': 'db_2_passwd',
'HOST': 'db_2_host',
'PORT': 'db_2_port',
},
}
I use Django-nose for running test suits and use Django 2.2
You could use the database parameter in your tests.
For example:
class TestYourClass(TestCase):
databases = {'default', 'mig'}
def test_some_method(self):
call_some_method()
For more information please see Multi-database support.
P.S. In earliest Django version than 2.2 please use multi_db = True
class TestYourClass(TestCase):
multi_db = True
You need to grant DJANGO user the priviledge to write.
Then, to make the tests and preserve your data, you have to make a copy of your schema with test_ as prefix and use the keywork --keepdb.
Trying to follow this tutorial: https://knivets.com/how-to-integrate-django-with-existing-database/
and this SO: Using existing database in Django
My settings.py databases setup:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
# existing db I wan't to add
'articles': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'articles.sqlite3'),
}
}
It does detect and generates a model based on the table I'm interested in. I've added this model to models.py and
python manage.py dbshell --database=articles
does show the table and that it holds data. However, in Django /admin the table shows up but breaks when I try to add to it and none of the existing data appears. This is the error that it throws:
OperationalError at /admin/core/articles/
no such table: articles
I appreciate any help ya'll can offer here.
In my project I am using multiple databases, 3 to be precise.
One default and two reference databases (another host), which are powered and updated by our data team. I am using 4 tables from 2 external databases, which were inspected with ./manage.py inspectdb. They are set to managed=False
Everything works fine, my application works as expected and planned.
Now the fun begins, I need to write tests. I do not want to delete my databases.
I need to read from them, I do not want to create fixtures.
Every time when I try to use pytest or custom django tests, it is trying to delete my databases, recreate, run migrations and stuff.
How can I preserve that ? Either in pytest or django tests ? I've tried to --re-usedb, and couple of another params.
This is my database settings (parts which can be uploaded)
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'default_db',
'USER': 'default_usr',
'PASSWORD': 'default_pass',
'HOST': 'postgres.somehost.com',
'SUPPORTS_TRANSACTIONS': True,
},
'geolocations': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'OPTIONS': {
'options': '-c search_path=some_schema'
},
'NAME': 'geo_name',
'USER': 'geo_user',
'PASSWORD': 'geo_password',
'HOST': 'some-host.domain.com',
'SUPPORTS_TRANSACTIONS': True,
},
'eoc': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'OPTIONS': {
'options': '-c search_path=another_schema'
},
'NAME': 'eco_name',
'USER': 'eoc_user',
'PASSWORD': 'eoc_',
'HOST': 'some-another-host.domain.com',
'SUPPORTS_TRANSACTIONS': True,
}
}
So inside of pytest.ini you should be able to add a '--no-migrations' flag in order to ensure that migrations are not being made. Using a pytest marker pytest documentation should enable you to have access to your database.
The mark you need is:
pytestmark = pytest.mark.django_db
I have installed app named registration-redux, and I would like to store user data (and some other minor things) in a sqlite database called default. However, the data structures get added automatically to other databases, which is redundant.
Normally, I go to models.py and put in a desired model a label:
class some_model(models.Model):
name = models.CharField(max_length=20, primary_key=True)
class Meta:
app_label = 'default'
And in settings.py I select which models go to which database:
DATABASE_APPS_MAPPING = {'market_data': 'market_data',
'registration': 'default'} # this doesn't work
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'market_data': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'market_data.sqlite3'),
}
}
Now, when I migrate market_data database, redundant structures like auth_user, auth_group, etc. get added. How can I omit them?
For Django 1.7
Create file routers.py, and in this file write:
class Market_data_router(object):
def allow_migrate(self, db, model):
if db == 'market_data':
if model.__name__ != 'Market_data':
return False
return None
In settings.py write:
DATABASE_ROUTERS = ['routers.Market_data_router']
At the end, create ,,clear" database:
./manage.py migrate --database=market_data
My django project uses 2 databases, 1 existing database and another one which I am creating through my project using Models. I have defined db's in settings.py as below :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'music': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'myMusicDb.sqlite3'),
}
}
I generated model data using inspectdb command and everything works fine if I remove the default db from settings.py and make the 'music' db the default db. My query is how to keep both db in settings.py and to work with both DataBases ? Is there any way to tell django to use specific database from settings.py ?
I found the answer after reading https://docs.djangoproject.com/en/1.7/topics/db/multi-db/.
We can either use routers or we can make use of using keyword in query such as -
Album.objects.using('music').all()
Thought to post it, may be it could help someone.