How can use Django, PostgreSQL, psycopg2, database parameters and multiple database schemas together?
When you start learning Django, first you started to use ORM and don't care about SQL. When you have found a bit more difficult issue and it is impossible to solve with it than you have to move to use Django Manager.raw(). Then you will reach the point, you have to learn, how can you execute custom SQL directly. Without any magic.
How can you use PostgreSQL in Django?
Install psycopg2 python module.
How can you use multiple schemas in Django?
You can declare in two places what kind of schema want to use.
First, you can set up in settings.py and it can use with connections parameter. If you don't specify the connection's key, Django will be using the default database:
Example multiple database setup in settings.py:
Second, you can declare the schemas in the raw SQL directly:
If you try to use parameters %s, %('key')s to change the schema it is impossible because you get back every time the variable with an apostrophe. It will cause SQL error: schema names can't be parameters because parameters only replace _data_ and not _identifiers_.
What was the solution?
At the end, I just removed the additional schema declaration from my FROM clause and I used without declaration at all. I just choose the right database connection as a parameter with the connection function.
How can you use PostgreSQL in Django?
Install psycopg2 python module.
How can you use multiple schemas in Django?
You can declare in two places what kind of schema want to use.
First, you can set up in settings.py and it can use with connections parameter. If you don't specify the connection's key, Django will be using the default database:
Example multiple database setup in settings.py:
DATABASES = {Then you can choose the right key of the connections in the models.py:
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'options': '-c search_path=schema_nameA',
'client_encoding': 'UTF8',
},
'NAME': 'dbname',
'USER': 'username',
'PASSWORD': '*****',
'HOST': '192.168.1.10',
'PORT': '5432'
},
'db1': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'options': '-c search_path=schema_nameB'},
'NAME': 'dbname',
'USER': 'username',
'PASSWORD': '*****',
'HOST': '92.168.1.10',
'PORT': '5432',
}
}
It's important you have to use the database alias (default, db1) not the schema name or database name.from django.db import connections with connections['db1'].cursor() as cursor: # Your code here...
Second, you can declare the schemas in the raw SQL directly:
I tested, In every time the FROM schema.table declaration was stronger. It overwrites the specified connections key than you get the result. (What was declared in the SQL's FROM clause.)from django.db import connection def my_custom_sql(self): with connection.cursor() as cursor: cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz]) cursor.execute("SELECT foo FROM schema.bar WHERE baz = %s", [self.baz]) row = cursor.fetchone() return row
If you try to use parameters %s, %('key')s to change the schema it is impossible because you get back every time the variable with an apostrophe. It will cause SQL error: schema names can't be parameters because parameters only replace _data_ and not _identifiers_.
What was the solution?
At the end, I just removed the additional schema declaration from my FROM clause and I used without declaration at all. I just choose the right database connection as a parameter with the connection function.
SELECT foo FROMschema.bar WHERE baz = %s
If you have sub-queries with different schemas it will be work fine, don't have to care about the database connection, remember, RAW SQL schema declarations are every time stronger.from django.db import connections with connections['db1'].cursor() as cursor: # Your code here...
Megjegyzések
Megjegyzés küldése