Re: Creating dynamically-typed tables using psycopg2's built-informatting - Mailing list psycopg

From Adrian Klaver
Subject Re: Creating dynamically-typed tables using psycopg2's built-informatting
Date
Msg-id 356f506e-1cbd-be9a-0fd6-bc1e50d9c9e1@aklaver.com
Whole thread Raw
In response to Creating dynamically-typed tables using psycopg2's built-in formatting  (Daniel Cohen <daniel.m.cohen@berkeley.edu>)
List psycopg
On 6/13/19 12:28 PM, Daniel Cohen wrote:
> Hi!
> 
> I'm working on a project in Python that interacts with a PostgreSQL data 
> warehouse, and I'm using the psycopg2 API. I am looking to create 
> dynamically-typed tables.
> 
> For example, I would like to be able to execute the following code:
> 
> |frompsycopg2 importconnect,sql connection 
>
=connect(host="host",port="port",database="database",user="user",password="pw")defcreate_table(tbl_name,col_name,col_type):query

> =sql.SQL("CREATE TABLE {} ({} 
>
{})".format(sql.Identifier(tbl_name),sql.Identifier(col_name),sql.Identifier(column_type)))connection.execute(query)create_table('animals','name','VARCHAR')|
> 
> and end up with a table named "animals" that contains a column "name" of 
> type VARCHAR. However, when I attempt to run this, I get an error: 
> *'type "VARCHAR" does not exist'*. I assume psycopg2's built-in 
> formatter is putting double quotes around the VARCHAR type when there 
> should not be any. Normally, I would just work around this myself, but 
> the documentation is/very/clear that Python string concatenation should 
> never be used for fear of SQL injection attacks. Security is a concern 
> for this project, so I would like to know if it's possible to create 
> dynamically-typed tables in this fashion using pyscopg2, and if not, 
> whether there exists another third-party API that can do so securely.
> 
> A second issue I've had is that when creating tables with a similar 
> methodology, the sql.Identifier() function does not perform as I expect 
> it to. When I use it to dynamically feed in table names, for example, I 
> get varying results. See below:|
> |
> 
> |CREATE TABLE tbl AS SELECT * FROM other_tbl;|
> 
> in raw SQL creates a table called tbl, whereas
> 
> |cursor.execute(sql.SQL("CREATE TABLE {} AS SELECT * FROM 
> other_tbl").format(sql.Identifier(tbl))|
> 
> creates a table called "tbl". The two are different, and

I'm not seeing it:

cursor.execute(sql.SQL("CREATE TABLE {} AS SELECT * FROM 
t1").format(sql.Identifier("tbl")))

test_(aklaver)> \d
...
public | t1                     | table    | aklaver
public | tbl                    | table    | aklaver
...

The question then becomes how is the variable tbl in your script being 
assigned to?

> 
> |SELECT * FROM tbl;|
> 
> ||
> 
> returns a totally different table than
> 
> SELECT * FROM "tbl";
> 
> Please let me know if I can fix either of these problems; I want to be 
> able to dynamically feed types into SQL queries, and I want the tables 
> created to be of the form tbl not "tbl". Thank you!
> 
> Danny
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com



psycopg by date:

Previous
From: Federico Di Gregorio
Date:
Subject: Re: Creating dynamically-typed tables using psycopg2's built-informatting
Next
From: Christophe Pettus
Date:
Subject: Re: Creating dynamically-typed tables using psycopg2's built-informatting