我对sqlalchemy很新。我在网上搜索过,无法在论坛或sqlalchemy文档中找到任何有用的信息。
我在: Python 3.4 sqlalchemy 1.0.11
以下是相关的代码段:
models.py
from sqlalchemy import Table, Column, ForeignKey, Integer, String, Date, Numeric, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
from sqlalchemy.ext.associationproxy import association_proxy
Base = declarative_base()
emp_exemptions_table = Table('emp_exemptions', Base.metadata,
Column('employee_id',
Integer,
ForeignKey('employee.id'),
primary_key=True),
Column('exemptReasons_id',
Integer,
ForeignKey('exemptReasons.id'),
primary_key=True)
)
current_exemptions_table = Table('current_exemptions', Base.metadata,
Column('exemption_id',
Integer,
ForeignKey('exemption.id'),
primary_key=True),
Column('exemptReasons_id',
Integer,
ForeignKey('exemptReasons.id'),
primary_key=True)
)
class ExemptReasons(Base):
__tablename__ = 'exemptReasons'
id = Column(Integer, primary_key=True)
text = Column('exemptReasons',
String(30),
nullable=True)
def __init__(self, text):
self.text = text
class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
eid = Column(String(8), nullable=False)
hours = Column(Numeric(), nullable=False)
exempt = Column(Boolean(), nullable=False)
exempt_reasons = relationship(ExemptReasons,
secondary=lambda: emp_exemptions_table)
as_of_date = Column(Date())
# proxy the 'exempt_reason' attribute from the 'exempt_reasons' relationship
reasons = association_proxy('exempt_reasons', 'text')
class CurrentExemption(Base):
__tablename__ = 'exemption'
id = Column(Integer, primary_key=True)
eid = Column(String(8), nullable=False)
effective_date = Column(Date())
exempt = Column(Boolean(), nullable=False)
exempt_reasons = relationship(ExemptReasons,
secondary=lambda: current_exemptions_table)
# proxy the 'exempt_reason' attribute from the 'exempt_reasons' relationship
reasons = association_proxy('exempt_reasons', 'text')
engine = create_engine('sqlite:///sqldb_example.db')
Base.metadata.create_all(engine)
相关功能
def determine_eligibility_changes(self, elig):
engine = create_engine('sqlite:///sqldb_example.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
student_reason = session.query(ExemptReasons).filter_by(text='Student Rule 3121(b)(10)').first()
new_exemptions = []
for e in elig:
current_elig = session.query(Employee).filter_by(eid=e['eid']).first() #todo: add time filter
if current_elig.reasons:
new_elig_reasons = current_elig.reasons
else:
new_elig_reasons = []
if e['eligible']:
if current_elig.exempt:
if not (student_reason.text in current_elig.reasons):
new_elig_reasons.append(student_reason.text)
else:
new_elig_reasons.append(student_reason.text)
else: # not eligible now
if current_elig.exempt:
if student_reason.text in current_elig.reasons:
new_elig_reasons.remove(student_reason.text)
e['exempt_reasons'] = new_elig_reasons
new_exemptions.append(e)
session.close()
return new_exemptions
def store_current_eligibility(self, lines):
engine = create_engine('sqlite:///sqldb_example.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
for x in lines:
new_eligibility = CurrentExemption(eid=x['eid'],
effective_date=datetime.today(),
exempt=x['eligible'],
reasons=x['exempt_reasons'],
)
session.add(new_eligibility)
session.commit()
回溯
Traceback (most recent call last):
File "start_calculator.py", line 5, in <module>
app.run()
File "/Users/hayne/bitbucket/APP005/app005/main_calculator.py", line 42, in run
EligibilityCalculator.store_current_eligibility(self, new_list)
File "/Users/hayne/bitbucket/APP005/app005/calculator/eligibility.py", line 134, in store_current_eligibility
reasons=x['exempt_reasons'],
File "<string>", line 4, in __init__
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/orm/state.py", line 306, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 183, in reraise
raise value
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/orm/state.py", line 303, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 649, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 283, in __set__
self._set(proxy, values)
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 352, in _set
proxy.extend(values)
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 617, in extend
for v in values:
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 604, in __iter__
for member in self.col:
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 509, in <lambda>
col = property(lambda self: self.lazy_collection())
File "/Users/hayne/.virtualenvs/APP005/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 465, in __call__
"stale association proxy, parent object has gone out of "
sqlalchemy.exc.InvalidRequestError: stale association proxy, parent object has gone out of scope
所以当我运行它时,当我尝试填充m2m键的原因时,它就会出现错误。它确实超过了第一条记录的提交,并在第二条记录上轰炸。第一个记录在列表中有一个值,但第二个记录没有值。我已将空列表存储到代码中其他位置的关系字段中,因此我不认为这是问题所在。问题是我如何从determine_eligibility_changes中的列表中删除元素?我不能简单地从列表中删除它吗?是否需要做其他事情?