我想創建一個SQLAlchemy對象的新實例,以便字段充滿默認值,但我想提交到數據庫生成一行UPDATE
已經存在相同的主鍵,有效地將其重置爲默認值。有沒有簡單的方法來做到這一點?SQLAlchemy:替換對象與一個新的,以下默認值
2
A
回答
0
我試圖做到這一點,並失敗,因爲SQLAlchemy會話跟蹤對象的狀態。所以沒有簡單的方法讓會話將新對象作爲持久對象來跟蹤。
但是你想將對象重置爲默認值,是嗎?有一個簡單的方法可以做到這一點:
from sqlalchemy.ext.declarative import declarative_base
class Base(object):
def reset(self):
for name, column in self.__class__.__table__.columns.items():
if column.default is not None:
setattr(self, name, column.default.execute())
Base = declarative_base(bind=engine, cls=Base)
這將reset
方法添加到所有模型類。
下面是完整的工作示例亂動:
import os
from datetime import datetime
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import functions
here = os.path.abspath(os.path.dirname(__file__))
engine = create_engine('sqlite:///%s/db.sqlite' % here, echo=True)
Session = sessionmaker(bind=engine)
class Base(object):
def reset(self):
for name, column in self.__class__.__table__.columns.items():
if column.default is not None:
setattr(self, name, column.default.execute())
Base = declarative_base(bind=engine, cls=Base)
class Thing(Base):
__tablename__ = 'things'
id = Column(Integer, primary_key=True)
value = Column(String(255), default='default')
ts1 = Column(DateTime, default=datetime.now)
ts2 = Column(DateTime, default=functions.now())
def __repr__(self):
return '<Thing(id={0.id!r}, value={0.value!r}, ' \
'ts1={0.ts1!r}, ts2={0.ts2!r})>'.format(self)
if __name__ == '__main__':
Base.metadata.drop_all()
Base.metadata.create_all()
print("---------------------------------------")
print("Create a new thing")
print("---------------------------------------")
session = Session()
thing = Thing(
value='some value',
ts1=datetime(2014, 1, 1),
ts2=datetime(2014, 2, 2),
)
session.add(thing)
session.commit()
session.close()
print("---------------------------------------")
print("Quering it from DB")
print("---------------------------------------")
session = Session()
thing = session.query(Thing).filter(Thing.id == 1).one()
print(thing)
session.close()
print("---------------------------------------")
print("Reset it to default")
print("---------------------------------------")
session = Session()
thing = session.query(Thing).filter(Thing.id == 1).one()
thing.reset()
session.commit()
session.close()
print("---------------------------------------")
print("Quering it from DB")
print("---------------------------------------")
session = Session()
thing = session.query(Thing).filter(Thing.id == 1).one()
print(thing)
session.close()
0
有沒有什麼簡單的方法來做到這一點?
經過進一步的考慮,並不是真的。最簡潔的方法是在__init__
中定義默認值。從DB獲取對象時從不調用構造函數,所以它非常安全。您還可以使用後端功能,例如current_timestamp()
。
class MyObject(Base):
id = Column(sa.Integer, primary_key=True)
column1 = Column(sa.String)
column2 = Column(sa.Integer)
columnN = Column(sa.String)
updated = Column(sa.DateTime)
def __init__(self, **kwargs):
kwargs.setdefault('column1', 'default value')
kwargs.setdefault('column2', 123)
kwargs.setdefault('columnN', None)
kwargs.setdefault('updated', sa.func.current_timestamp())
super(MyObject, self).__init__(**kwargs)
default_obj = MyObject()
default_obj.id = old_id
session.merge(default_obj)
session.commit()
+0
你確定嗎?這對我來說根本不起作用。實際上,在提交之後,我保持原始對象不變,就好像沒有任何事情發生一樣。 –
+0
其實我只是注意到我的測試代碼使用__init__來設置一些值,這看起來有很大的不同。合併適用於編輯的值,但不會觸發default()。您始終可以創建一個新實例,複製密鑰,刪除舊的並添加新的實例。 –
相關問題
- 1. 默認對象值的值
- 2. 熊貓替換默認值
- 3. 默認對象值
- 4. 無法與對象的默認值
- 5. 超級與sqlalchemy mixins默認值
- 6. 用JavaScript替換對象值與同一個鍵的其他對象的值
- 7. 對象參數的接口與默認值和默認屬性
- 8. C++函數,我可以給一個對象什麼默認值?
- 9. SQLAlchemy將一列的默認值設置爲另一列的默認值
- 10. 對象中的替換值與jQuery
- 11. 麪包::板的默認/可替換值
- 12. Doctrine2 - 與默認值一對多關係
- 13. 用默認文本替換空值
- 14. 如何用另一個對象的值替換多個對象值?
- 15. 替換默認的MessageBox
- 16. 替換默認的TomcatServerFactory
- 17. 我可以在Axis2默認下載中替換最新版本的mail.jar嗎?
- 18. 推新對象替換以前的對象
- 19. 如何翻譯 - 用另一個對象的值替換對象的值
- 20. 問題與DataGridView中列默認值添加一個新的行
- 21. 提供一個默認值與ValidateSet
- 22. ListView替換第一個對象而不是添加一個新對象
- 23. 默認情況下創建一個枚舉對象惰性
- 24. 準備默認新行作爲空值替換
- 25. 自動替換模塊中的每個函數的默認值
- 26. 替換與第一以下非楠值的NaN(列 - 明智)
- 27. 表單對象字段的默認值
- 28. WPF DataGrid - 生成對象的默認值
- 29. JavaScript中選項對象的默認值
- 30. 使用默認值的Javascript對象
這隻適用於具有標量默認值的列。函數,上下文函數和sql表達式都將導致失敗。 – davidism
我更新了我的答案。現在這個例子可以和用戶定義的函數以及服務器端默認一起使用。 –
不幸的是,重置方法並不能解決我的問題。是的,我想重置爲默認值,但通過創建具有默認值的新實例來實現這一點非常重要,並且可以在插入新實例或更新現有值之間進行選擇。 –