2013-05-06 1 views
3

SQLalchemy를 사용하는 레거시 MSSQL 데이터베이스에서 작업하고 있는데,이를 위해 선언적 매핑이 있습니다.
이 데이터베이스에는 개의 계산 열이있는 여러 테이블이 있습니다. 나는 그것들을 잘 읽을 수 있지만 (물론) 계산 된 컬럼에 쓰는 것은 효과가 없다. 그러나 ORM 개체를 만들고 저장할 때 SQLAlchemy는 여전히이 열에 '없음'값을 저장하려고 시도하여 오류가 발생합니다.sqlalchemy에서 계산 된 열이있는 테이블을 업데이트하십시오.

SQLAlchemy의 hybrid_property 데코레이터를 사용하여 특정 열을 "읽기 전용"으로해야하는 온라인 예제를 찾았지만이를 구현 한 후에도 동일한 오류 (The column "tlog_real_timehh" cannot be modified because it is either a computed column or is the result of a UNION operator.)가 계속 나타납니다.

다음과 같이 코드는 - 매핑 :

rem = Transactionlog() 
    rem.tlog_testrun = 0 
    rem.tlog_evtt_id = 'rem' 
    rem.tlog_Data = None 
    rem.tlog_comment = 'reminder' 
    rem.tlog_price = 0 
    db.session.add(rem) 
    db.session.flush() 

내가 hybrid_property 코드가 계산 필드는 읽기 - 수 있도록 기대 : 새 레코드를 추가해야

class transactionlog(Base): 
    __tablename__ = 'transactionlog' 
    tlog_id = Column(VARCHAR(length=36), primary_key=True, nullable=False) 
    tlog_ppl_id = Column(VARCHAR(length=36), ForeignKey('people.ppl_id')) 
    tlog_evtt_id = Column(VARCHAR(length=5)) 
    tlog_testrun = Column(BIT()) 
    tlog_Data = Column(NVARCHAR(length=300)) 
    tlog_price = Column(DECIMAL(precision=18, scale=2)) 
    tlog_comment = Column(NVARCHAR(length=1000)) 
    _tlog_real_timehh = Column('tlog_real_timehh', INTEGER()) 
    _tlog_real_timemm = Column('tlog_real_timemm', INTEGER()) 
    _tlog_real_timess = Column('tlog_real_timess', INTEGER()) 
    _tlog_fin_booking = Column('tlog_fin_booking', BIT()) 

    @hybrid_property 
    def tlog_real_timehh(self): 
     return self._tlog_real_timehh 

    @tlog_real_timehh.setter 
    def tlog_real_timehh(self, tlog_real_timehh): 
     self._tlog_real_timehh = tlog_real_timehh 

    @hybrid_property 
    def tlog_real_timemm(self): 
     return self._tlog_real_timemm 

    @tlog_real_timemm.setter 
    def tlog_real_timemm(self, tlog_real_timemm): 
     self._tlog_real_timemm = tlog_real_timemm 

    @hybrid_property 
    def tlog_real_timess(self): 
     return self._tlog_real_timess 

    @tlog_real_timess.setter 
    def tlog_real_timess(self, tlog_real_timess): 
     self._tlog_real_timess = tlog_real_timess 

    @hybrid_property 
    def tlog_fin_booking(self): 
     return self._tlog_fin_booking 

    @tlog_fin_booking.setter 
    def tlog_fin_booking(self, tlog_fin_booking): 
     self._tlog_fin_booking = tlog_fin_booking 

하고 코드를 그러나 SQLAlchemy는 여전히 매핑 코드를 기반으로 INSERT 문에서 SQLAlchemy를 채우려 고 시도합니다. (나는 SQL 문을 보았을 때 이것을 볼 수 있는데, SQL 문을 게시 할 수 없다. StackOverflow에 민감한 데이터가 없기 때문에 객체를 다소 간략하게했기 때문이다.)

질문은 SQLAlchemy가 tlog_real_timehh, tlog_real_timemm, tlog_real_timess 및 tlog_fin_booking에 값을 삽입하려고하는 이유는 무엇입니까? 어떻게 방지 할 수 있습니까?

어떤 포인터를 주셔서 감사합니다.
에릭

답변

3

FetchedValue와 라벨 server-generated columns :

from sqlalchemy import * 
from sqlalchemy.orm import * 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class A(Base): 
    __tablename__ = 'a' 

    id = Column(Integer, autoincrement=False, primary_key=True) 
    firstname = Column(String(50)) 
    lastname = Column(String(50)) 
    fullname = Column(String(100), FetchedValue()) 

e = create_engine("mssql+pyodbc://scott:[email protected]_2005", echo=True) 
Base.metadata.drop_all(e) 

e.execute(""" 
    CREATE TABLE a (
      id INTEGER PRIMARY KEY, 
      firstname VARCHAR(50), 
      lastname VARCHAR(50) 
     ) 
""") 
e.execute("ALTER TABLE a ADD fullname AS firstname + ' ' + lastname") 

sess = Session(e) 

sess.add_all([ 
    A(id=1, firstname='ed', lastname='jones'), 
    A(id=2, firstname='wendy', lastname='smith'), 
    A(id=3, firstname='jack', lastname='bean') 
]) 
sess.commit() 

assert [ 
    fname for fname, in 
    sess.query(A.fullname).order_by(A.id) 
] == ['ed jones', 'wendy smith', 'jack bean'] 


e.execute("DROP TABLE a") 
+0

을, 기초적인 테스트, 구현이! 감사 zzzeek 작동처럼 보인다! –

관련 문제