Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to do an insert with SQLAlchemy 0.9 and PostgreSQL 9.1, using SQL Expression Language. I'm new to sqlalchemy and can't use ORM at the moment because of reasons. My original solution uses a text query which needs to reference a pseudo column in an INSERT FROM SELECT.

My question is: How can I convert it from a text statement to an expression?

Any help will be very appreciated!!

This is my Original query, simplified (other columns were removed):

statement = """
CREATE TEMP TABLE tmp( event_id );
COPY tmp FROM '%(csv_file)s' WITH CSV HEADER QUOTE '''';
INSERT INTO permanent_table ( source_system, event_id )
SELECT '%(src)s', tmp.event_id
FROM tmp
LEFT JOIN permanent_table pt ON (tmp.event_id=pt.event_id AND pt.source_system='%(src)'
WHERE pt.event_id IS NULL;
""" % {'csv_file':somefile, 'src':'SYS1'}

And I currently run it this way:

with engine.begin() as conn:
  result = conn.execute(statement)

This works and does what I need but I don't get feedback inside 'result'. I need to know how many rows were inserted, if any, but the value or 'result' is always None even if it does insert rows. That's the reason I want to convert it.

This is what I have done so far, but I can't figure out how to put the insert statement together...

with engine.begin() as conn:
  pt = sqlalchemy.Table('permanent_table',metadata,autoload=True,autoload_with=engine, schema='test')
  tmp = Table('tmp',metadata,Column('event_id', String(100)))
  metadata.create_all()
  copy_statement = """COPY tmp FROM '%(csv_file)s' WITH CSV HEADER QUOTE'''';""" % {'csv_file':somefile}
  s=select([tmp])
  result = conn.execute(s).fetchone()
  print result

With the above I can verify that I am inserting stuff into 'tmp':

result (u'113938227820000400')    

How do I actually construct the insert tho? This fails:

insert_statement = pt.insert().from_select(
   ['source_system','event_id'],
   tmp.select(['%(src)s', tmp]).join( pt,
      pt.c.event_id==tmp.c.event_id).where(pt.c.event_id==None)
result=conn.execute(insert_statement)

Thanks in advance!!

share|improve this question
    
Don't use a multi-statement. Run each statement individually. –  Craig Ringer Mar 4 at 0:41
    
sorry @CraigRinger, do you mean to break the original into multiple executes? Could you clarify a bit please? –  Raider of the lost BBS Mar 4 at 0:45
    
Yes, run each statement with an individual execute. Otherwise PostgreSQL doesn't know which one you want a result set or rowcount from. –  Craig Ringer Mar 4 at 0:51
    
I broke it down into individual statements, but when I execute the insert, I still can't get back the number of rows inserted. When I run this: conn.execute(insert_statement).fetchall() I get ResourceClosedError: This result object does not return rows. It has been closed automatically. :( –  Raider of the lost BBS Mar 4 at 1:57
    
the new insert_statement is simply "INSERT INTO permanent_table ( source_system, event_id ) SELECT '%(src)s', tmp.event_id FROM tmp LEFT JOIN permanent_table pt ON (tmp.event_id=pt.event_id AND pt.source_system='%(src)' WHERE pt.event_id IS NULL;" by itself as suggested. –  Raider of the lost BBS Mar 4 at 2:04

1 Answer 1

up vote 1 down vote accepted

Rowcounts aren't accessed via fetch commands. Those are to get result sets.

Use cursor.rowcount to get the rowcount, per the psycopg2 documentation.

share|improve this answer
    
Ah, that does it, thank you very much! –  Raider of the lost BBS Mar 4 at 3:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.