Why doesn't SQLAlchemy reflect tables in non-public schema? - postgresql

I have a PostgreSQL database, which has had all objects in public schema.
Used SQLAlchemy to succesfully connect to it and reflect objects from it.
Now I needed to create a separate schema schema2 in the same database. I assigned to new user all rights in that schema, checked that I can connect from command line with psql and do things in it.
But SQLAlchemy doesn't see any tables in the schema, when I try to use the same method to reflect its tables -- despite trying various ways to specify schema!
This is what worked for initial connection to public schema:
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine
from sqlalchemy import Table, Integer, String, Text, Column, ForeignKey
Base=automap_base()
sql_conn='postgres://my_user#/foo'
engine=create_engine(sql_conn)
Base.prepare(engine, reflect=True)
Then I could use Base.classes.* for tables and I didn't need to create Table classes on my own.
Now, this same works for this new user for public schema as well.
But whenever I somehow try to pass the schema2 to reflect tables from schema2, I always get empty Base.classes.*
I tried all the solutions in SQLAlchemy support of Postgres Schemas but I don't get anything at all reflected!
I tried:
making user's default schema schema2 via SQL means:
ALTER new_user SET search_path=schema2;
tried to pass schema in engine.connect via engine options
tried to set schema in MetaData and use that, as per SQLAlchemy docs:
Doing:
meta=MetaData(bind=engine,schema='schema2')
meta.reflect()
does work, as I can see all the tables correctly in meta.tables afterwards.
However, when I try to get Base.classes working as per SQLAlchemy automapper docs, the Base.classes don't get populated:
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine
from sqlalchemy import Table, Integer, String, Text, Column, ForeignKey, MetaData
sql_conn='postgres://new_user#/foo'
engine=create_engine(sql_conn)
meta=MetaData(bind=engine,schema='schema2')
Base=automap_base(metadata=meta)
Base.prepare(engine, reflect=True)
Base.classes is empty...
I am now stumped. Any ideas?
PS. I am working on newest SQLAlchemy available (1.3) under pip for Python2.7, Ubuntu 18.04LTS.

Related

Question. oracle_fdw - Import foreign schema limit to synonym?

oracle_fdw - β€ŽIs it possible in PostgreSQL to import foreign schema with a limit to synonym - as in the attached image?
γ…€
For example, this not working (limit to synonym):
IMPORT FOREIGN SCHEMA "UserA" LIMIT TO (A_SYNONYM) FROM SERVER oracledb INTO public;
but works when I try to import foreign schemat limit to view or table:
IMPORT FOREIGN SCHEMA "UserB" LIMIT TO (B_VIEW) FROM SERVER oracledb INTO public;
β€Ž
So, it is possible to use synonyms in import foreign schema "LIMIT TO ()"?
β€Ž
When processing IMPORT FOREIGN SCHEMA, oracle_fdw searches through the Oracle view ALL_TAB_COLUMNS in Oracle. According to the Oracle documentation
ALL_TAB_COLUMNS describes the columns of the tables, views, and clusters accessible to the current user.
That sounds like synonyms won't be listed. You can easily test that by omitting the LIMIT TO clause. If foreign tables for synonyms are not created, you have a proof.
As a workaround, you could import those tables from the schemas where they really reside.

How to create a new schema from a flask application

I have flask application,I'm trying to achieve multi-tenancy by multiple schema for users. When a user sign up, i'm trying to create a new schema with the username from the application and creating new two table in that particular schema.
i can create a new schema into the database using psql console using
postgres=# CREATE SCHEMA schema_name;
How can i create the schema from the flask application?
I have achieved the same. My aim was to create a SaSS app with a shared DB & separate schema in Flask.
So when users signup for my premium plan, my code will create a schema for my user.
First import the required modules.
from sqlalchemy import create_engine, MetaData, Table
In the user sign-up route, I have added the below code. The org_id is a random string & it is my schema. Also, I have to create a post table inside that schema. I also need to save the schema name in my user table & it helps to filter result later in that schema only.
# Create schema
engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
if not engine.dialect.has_schema(engine, org_id):
engine.execute('CREATE SCHEMA IF NOT EXISTS %s' % org_id)
# Create table inside this new schema
if engine.dialect.has_schema(engine, org_id):
meta = MetaData()
post = Table('post', meta,
db.Column('id', db.Integer, primary_key=True),
db.Column('body', db.String(140)),
db.Column('timestamp', db.DateTime, index=True, default=datetime.utcnow),
db.Column('user_id', db.Integer),
schema=org_id
)
post.create(engine)
Basically I'm a beginner in flask & python. So I'm not sure what is the correct method.

Error while importing tables in postgreSQL

i am trying to import table individually using UI. I am directly importing table without creating it prior.
It gives me error message to Create the table before import.
but import option should create table structure according to file columns.
How to import without creating tables prior using PostgreSQL?
In this case ,TABLE according to the import file must be created first. IF there is no prior table , it wont work.
This may help.
http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/

sqlachemy explanation of schema generation

I am trying to use sqlalchemy to create a schema in postgres. I cannot find a working example of the method of creating the schema via the MetaData and reflect function where one declares the name of the schema.
conn = db.postgres_db(host, port, database, pass, user)
postg_meta = sql.MetaData(bind=conn.engine)
postg_meta.reflect(schema='transactions')
stat_query = sql.select([sql.distinct(acocunts.c.user_id)]
This is a snippet of the code given to me and I am attempting to clarify where and how the schema ('transactions') is defined. I am new to sqlalchemy and the rational of some of its working pieces so I would appreciate some assistance.
Could this refer to a file with an external class where the schema is defined?
Thanks.
Postgres has the concept of a schema which is hierarchically ordered between the database and table like database.schema.table.
SQLAlchemy supports this concept of schemas for Postgres and other databases.
Since you performing a reflection, it is implicit that this schema already exists in your database. This is what the schema keyword is referring to.
You can confirm that this is the case by listing all the schemas in your database:
select schema_name
from information_schema.schemata

Create PostgreSQL schemas before create_all function start creating the tables in Flask-SQLAlchemy

I am starting to develop an application with Flask and PostgreSQL for my back-end and I am using PostgreSQL schemas.
My problem is that, when I call the database.create_all() function, SQLalchemy thrown me an error because the schema doesn't exist.
I trying to create the required schemas before the creation process start, using SQLAlchemy events and CreateSchema, but I don't understand well how to use the CreateSchema, with the next code:
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.event import listens_for
from sqlalchemy.schema import CreateSchema
database = SQLAlchemy()
#listens_for(database.metadata, 'before_create')
def create_schemas(target, b, **kw):
CreateSchema('app')
database.session.commit()
The listener is called, but the error still persist. The schema isn't being created in the database.
NOTE:
The database is initialized with the Flask application instance in another module as following:
from .model import database
database.init_app(app)
with app.app_context():
database.create_all()
So, I am not getting any problem related to application context.
EDIT:
CreateSchema represent a CREATE SCHEMA sql statement, that must be executed with database.session.execute(CreateSchema('app')).
Now I realize that the listener is called every time one table is created, throwing the error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) schema "app" already exists
Thanks.
The fast way I solved my problem was creating the schemas right before I call database.create_all(). I used the statement CREATE SCHEMA IF NOT EXISTS schema_name that creates a schema just if it doesn't exist. This statement is just available starting from PostgreSQL 9.3
# my model module
def create_schemas():
""" Note that this function run a SQL Statement available just in
PostgreSQL 9.3+
"""
database.session.execute('CREATE SCHEMA IF NOT EXISTS schema_name')
database.session.execute('CREATE SCHEMA IF NOT EXISTS schema_name2')
database.session.commit()
I initializing the database and calling the function from another module:
from .model import database, create_schemas
database.init_app(app)
with app.app_context():
create_schemas()
database.create_all()
Well, this is a solution that works for my specific situation.