Thread: VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

From
Christopher Brooks
Date:
I'm using SQLAlchemy backed by psychopg2 to interact with my data inside of AWS Redshift.  I'm trying to insert data and am getting a perplexing error with respect to text vs varchar data.  Here is a source snipit:

conn = get_db_connection()
keys=["a","b"]
values=["aa","bb"]

tbl_qualtrics_dim = Table('qualtrics_dim', metadata,
                 Column('k', String(1024), primary_key=True),
                 Column('v', String(1024), nullable=False)
                 )
metadata.create_all(conn, checkfirst=True)
ins = tbl_qualtrics_dim.insert().values(k=keys, v=values)
conn.execute(ins)

This creates the table just fine as being two columns of varchar(1024).  AWS doesn't support clob types.  The last line throws an error though when trying to insert data:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "k" is of type character varying but expression is of type text[]
HINT:  You will need to rewrite or cast the expression.
 [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (%(k)s, %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'k': ['a', 'b']}]

A cast as I understand it doesn't work, e.g. I change this line:

ins = tbl_qualtrics_dim.insert().values(k=cast(keys, String(1024)), v=values)

And I get a casting error:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) cannot cast type text[] to character varying
 [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (CAST(%(param_1)s AS VARCHAR(1024)), %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'param_1': ['a', 'b']}]

Any hints on what might be going wrong here? 

Regards,

Chris

Re: VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

From
Christophe Pettus
Date:
On Aug 30, 2015, at 11:59 AM, Christopher Brooks <brooksch@umich.edu> wrote:
>  [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (%(k)s, %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'k': ['a', 'b']}]

The values you've written there are two arrays of TEXT values, but the columns aren't declared as TEXT or VARCHAR
arrays,but as single VARCHAR values.  Are you trying to insert two rows of the form 'aa', 'a' and 'bb', 'b'? 

--
-- Christophe Pettus
   xof@thebuild.com



Re: VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

From
Christopher Brooks
Date:
Yes, this is what I was aiming to do.  Maybe I've got the sql alchemy syntax wrong?  I though insert().values took in iterables for row by row inserts...

Chris

On Sun, Aug 30, 2015 at 3:01 PM, Christophe Pettus <xof@thebuild.com> wrote:

On Aug 30, 2015, at 11:59 AM, Christopher Brooks <brooksch@umich.edu> wrote:
>  [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (%(k)s, %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'k': ['a', 'b']}]

The values you've written there are two arrays of TEXT values, but the columns aren't declared as TEXT or VARCHAR arrays, but as single VARCHAR values.  Are you trying to insert two rows of the form 'aa', 'a' and 'bb', 'b'?

--
-- Christophe Pettus
   xof@thebuild.com




--
Christopher Brooks, PhD
Research Fellow


Mail:School of Information
University of Michigan
4322 North Quad
105 S. State St.
Ann Arbor, MI 48109-1285

Re: VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

From
Adrian Klaver
Date:
On 08/30/2015 12:04 PM, Christopher Brooks wrote:
> Yes, this is what I was aiming to do.  Maybe I've got the sql alchemy
> syntax wrong?  I though insert().values took in iterables for row by row
> inserts...
>

Think you want to take a look here:

http://docs.sqlalchemy.org/en/rel_1_0/core/dml.html#sqlalchemy.sql.expression.Insert.values

in particular:

The Insert construct also supports multiply-rendered VALUES construct,
for those backends which support this SQL syntax (SQLite, Postgresql,
MySQL). This mode is indicated by passing a list of one or more
dictionaries/tuples:

users.insert().values([
                     {"name": "some name"},
                     {"name": "some other name"},
                     {"name": "yet another name"},
                 ])


> Chris
>
> On Sun, Aug 30, 2015 at 3:01 PM, Christophe Pettus <xof@thebuild.com
> <mailto:xof@thebuild.com>> wrote:
>
>
>     On Aug 30, 2015, at 11:59 AM, Christopher Brooks <brooksch@umich.edu
>     <mailto:brooksch@umich.edu>> wrote:
>     >  [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (%(k)s, %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'k': ['a',
'b']}]
>
>     The values you've written there are two arrays of TEXT values, but
>     the columns aren't declared as TEXT or VARCHAR arrays, but as single
>     VARCHAR values.  Are you trying to insert two rows of the form 'aa',
>     'a' and 'bb', 'b'?
>
>     --
>     -- Christophe Pettus
>     xof@thebuild.com <mailto:xof@thebuild.com>
>
>
>
>
> --
> Christopher Brooks, PhD
> Research Fellow
>
> E-Mail: brooksch@umich.edu <mailto:brooksch@umich.edu>
> Web: http://www.si.umich.edu/people/christopher-brooks
>
> Mail:School of Information
> University of Michigan
> 4322 North Quad
> 105 S. State St.
> Ann Arbor, MI 48109-1285


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: VARCHAR versus TEXT when using psychopg2, sqlalchemy and redshift

From
Christopher Brooks
Date:
Thanks for this Adrian and Christophe, this was the issue!

Regards,

Chris

On Sun, Aug 30, 2015 at 3:49 PM, Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 08/30/2015 12:04 PM, Christopher Brooks wrote:
Yes, this is what I was aiming to do.  Maybe I've got the sql alchemy
syntax wrong?  I though insert().values took in iterables for row by row
inserts...


Think you want to take a look here:

http://docs.sqlalchemy.org/en/rel_1_0/core/dml.html#sqlalchemy.sql.expression.Insert.values

in particular:

The Insert construct also supports multiply-rendered VALUES construct, for those backends which support this SQL syntax (SQLite, Postgresql, MySQL). This mode is indicated by passing a list of one or more dictionaries/tuples:

users.insert().values([
                    {"name": "some name"},
                    {"name": "some other name"},
                    {"name": "yet another name"},
                ])


Chris

On Sun, Aug 30, 2015 at 3:01 PM, Christophe Pettus <xof@thebuild.com
<mailto:xof@thebuild.com>> wrote:


    On Aug 30, 2015, at 11:59 AM, Christopher Brooks <brooksch@umich.edu
    <mailto:brooksch@umich.edu>> wrote:
    >  [SQL: 'INSERT INTO qualtrics_dim (k, v) VALUES (%(k)s, %(v)s)'] [parameters: {'v': ['aa', 'bb'], 'k': ['a', 'b']}]

    The values you've written there are two arrays of TEXT values, but
    the columns aren't declared as TEXT or VARCHAR arrays, but as single
    VARCHAR values.  Are you trying to insert two rows of the form 'aa',
    'a' and 'bb', 'b'?

    --
    -- Christophe Pettus
    xof@thebuild.com <mailto:xof@thebuild.com>




--
Christopher Brooks, PhD
Research Fellow

E-Mail: brooksch@umich.edu <mailto:brooksch@umich.edu>
Web: http://www.si.umich.edu/people/christopher-brooks

Mail:School of Information
University of Michigan
4322 North Quad
105 S. State St.
Ann Arbor, MI 48109-1285


--
Adrian Klaver
adrian.klaver@aklaver.com



--
Christopher Brooks, PhD
Research Fellow


Mail:School of Information
University of Michigan
4322 North Quad
105 S. State St.
Ann Arbor, MI 48109-1285