2012-03-04 3 views
1

Это немного код, который я пишу для плагина для небольшого программного обеспечения (Anki).SqlAlchemy OperationalError using Case

for i in date: 
    self.deck.s.execute(
    """CASE WHEN EXISTS(SELECT * FROM :table WHERE day=date(:i)) THEN 
     UPDATE :table SET WHERE day=date(:i) 
     ELSE 
     INSERT INTO :table (day, matureRise) VALUES (date(:i),1) 
     END""", {'table':STATSTABLE,'i':i}) 

Проблема в том, что он продолжает бросать OperationalError. В частности, я получаю:

sqlalchemy.engine.default", line 299, in do_execute 
OperationalError: (OperationalError) near "CASE": syntax error u'CASE WHEN EXISTS(SELECT * FROM ? WHERE day=date(?)) THEN\nUPDATE ? SET WHERE day=date(?)\nELSE\nINSERT INTO ? (day, matureRise) VALUES (date(?),1) END' ('stats_2', (u'2011-05-03',), 'stats_2', (u'2011-05-03',), 'stats_2', (u'2011-05-03',)) 

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

+0

Uhh .. когда-либо слышал о 'INSERT ... ON DUPLICATE KEY UPDATE'? – plaes

+0

Ничего не исправить. Все еще получаю ошибку: sqlalchemy.exc.OperationalError: (OperationalError) рядом с «ON»: синтаксическая ошибка u «INSERT INTO stats_2 (day, ageRise) VALUES (дата ('2011-05-03'), 1) ON DUPLICATE KEY UPDATE ageRise = зрелыйRise + 1 – Jeremy

+0

Это поможет, если вы сообщите, какую базу данных вы используете. Это решение, которое я предложил, зависит от MySQL и не поддерживается SQLite. – plaes

ответ

0

Попробуйте

from sqlalchemy import create_engine 

engine = create_engine('mysql://test:[email protected]/test', echo=True) 
from sqlalchemy.orm import sessionmaker 

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Date, Column, Integer 


Base = declarative_base() 



class User(Base): 
    __tablename__ = 'users' 

    id = Column(Integer, primary_key=True, autoincrement=True) 
    day = Column(Date, unique=True) 


if __name__ == '__main__': 

    Base.metadata.create_all(engine) 
    c = engine.connect() 
    c.execute("""INSERT INTO users(day) VALUES ('2012-03-05') ON DUPLICATE KEY UPDATE day='2012-03-04'""") 

Когда я запустить этот файл первый раз, когда я войти, как

2012-03-05 12:39:42,202 INFO sqlalchemy.engine.base.Engine SELECT DATABASE() 
2012-03-05 12:39:42,202 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,204 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%' 
2012-03-05 12:39:42,204 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,205 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names' 
2012-03-05 12:39:42,205 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,206 INFO sqlalchemy.engine.base.Engine SHOW COLLATION 
2012-03-05 12:39:42,206 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,209 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode' 
2012-03-05 12:39:42,209 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,210 INFO sqlalchemy.engine.base.Engine DESCRIBE `users` 
2012-03-05 12:39:42,210 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,211 INFO sqlalchemy.engine.base.Engine INSERT INTO users(day) VALUES ('2012-03-05') ON DUPLICATE KEY UPDATE day='2012-03-04' 
2012-03-05 12:39:42,211 INFO sqlalchemy.engine.base.Engine() 
2012-03-05 12:39:42,212 INFO sqlalchemy.engine.base.Engine COMMIT 

Затем я проверить в базе данных

mysql> select * from users; 
+----+------------+ 
| id | day  | 
+----+------------+ 
| 8 | 2012-03-05 | 
+----+------------+ 
1 row in set (0.00 sec) 

Затем я снова запустите программу

и ch eck mysql снова.

mysql> select * from users; 
+----+------------+ 
| id | day  | 
+----+------------+ 
| 8 | 2012-03-04 | 
+----+------------+ 
1 row in set (0.00 sec) 
+0

Спасибо за ввод. В итоге я выяснил обходное решение/взломать мою проблему. В итоге я использовал INSERT ИЛИ IGNORE и затем проверяем, нет ли возврата, а затем UPDATING. Вероятно, вы, вероятно, будете работать, если я установлю свое дневное поле как KEY. Мне нравится его простота, и именно это я искал изначально si Я знал, что должно быть возможно INSERT или UPDATE в том же выполнении SQL. Я дам вам ответ. Благодарю. – Jeremy

Смежные вопросы