2014-01-26 2 views
1

я попытался адаптировать примеры here и hereКаков правильный способ вставки изображения в Postgres с помощью python?

import psycopg2 
#Given media_id and image_url and conn object 
image_data = urllib2.urlopen(image_url).read() 
sql =("INSERT INTO images (media_id, data) 
SELECT %s 
WHERE 
NOT EXISTS (SELECT media_id FROM images WHERE media_is = CAST(%s as TEXT) ") 
data_insert_image = (media_id, psycopg2.Binary(image_data)) 
cursor.execute(sql_insert_image, data_insert_image) 
conn.commit() 

результатов:

TypeError: not all arguments converted during string formatting 

Который имеет смысл для меня, как изображение не String; однако я не знаю, как правильно вставить. Как следует выполнить вставку?

+0

У вас есть два оператора SQL в вашем запросе. Я бы разделил их на две части. Оператор insert должен отлично работать с '' 'psycopg2.Binary''' – nathancahill

+0

@nathancahill, разбивая его на два запроса, не разрешает ошибку типа на вставке изображения. – SMTF

+0

. Вы делаете неправильный upsert там - это не будет работать перед лицом параллелизма. Мне не сразу понятно, почему Psycopg2 не нравится этот запрос; 'psycopg2.Binary (image_data)' действительно правильный подход для работы с данными bytea. Ваш запрос также вздор; 'INSERT' принимает' (media_id, data) ', но вы указали только аргумент' media_id' в 'SELECT'-list. –

ответ

2

У вашего сильно отредактированного кода есть много проблем, некоторые из которых уже указаны в комментариях. Я надеюсь, что этот пример достаточно ясен.

import psycopg2, urllib2 

image_url = 'http://example.com/theimage.jpg' 
image_data = urllib2.urlopen(image_url).read() 
media_id = 3 

# triple quotes allows better string formating 
sql = """ 
    with s as (
     select media_id 
     from images 
     where media_id = %(media_id)s 
    ) 
    insert into images (media_id, data) 
    select %(media_id)s, %(data)s 
    where not exists (select 1 from s) 
    returning media_id 
;""" 

# a parameter dictionary is clearer than a tuple 
data_insert_image = { 
    'media_id': media_id, 
    'data': psycopg2.Binary(image_data) 
} 

conn = psycopg2.connect("host=localhost4 port=5432 dbname=db user=u password=p") 
cursor = conn.cursor() 
cursor.execute(sql, data_insert_image) 
# fetchone returns a single tuple or null 
result = cursor.fetchone() 
conn.commit() 

if result is not None: 
    print 'Media Id {0} was inserted'.format(result[0]) 
else: 
    print 'Media Id {0} already exists'.format(media_id) 
Смежные вопросы