要約:SQLAlchemyにアドレスのリストを整列させたい。 コミットすると私のリストの順番が変わります。 なぜこれが起こり、どのように変更できますか?SQLAlchemy InstrumentedListの順序が永続的でないのはなぜですか?
ロング説明:
- 私はUserオブジェクトに添付アドレスのリストを開始します。
- 次に、「アドレス」リストの最初の要素を 新しいアドレスに置き換えます。
- 次に、私はアドレスのリストを印刷します...今のところ、注文は私が期待するものです。
- 最後にコミットします。コミット後、私はクエリを実行しますが、私の アドレスリストの順序が変更されました。
これは私が理解していない一般的なデータベースの一般的なことですか?または、SQLAlchemy InstrumentedListは実際のリストのように動作しませんか?私は関係の中で要素の順序を変えることができると思ったが、どのように見えるのか分からない。
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
Session = sessionmaker()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(12))
addresses = relationship("Address", back_populates="user")
def __repr__(self):
return "<User(name='%s', fullname='%s', password='%s')>" % (
self.name, self.fullname, self.password)
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User", back_populates="addresses")
def __repr__(self):
return "<Address(email_address='%s')>" % self.email_address
if __name__ == "__main__":
engine = create_engine('sqlite:///:memory:', echo=False)
Session.configure(bind=engine)
Base.metadata.create_all(engine)
session = Session()
user = User(name='ed', fullname='Ed Jones', password='edspassword')
user.addresses = [Address(email_address='[email protected]'), Address(email_address='[email protected]')]
session.add(user)
session.commit()
user = session.query(User).filter_by(name='ed').first()
print("Current order of addresses list at start.")
print(user.addresses)
print()
new_primary_address = Address(email_address='[email protected]')
user.addresses[0] = new_primary_address
print("Current order of addresses list before commit.")
print("But after chaning addresses[0].")
print(user.addresses)
print()
session.commit()
user = session.query(User).filter_by(name='ed').first()
print("Current order of addresses list after commit.")
print(user.addresses)
print()
print("Why is the order of the InstrumentedList not persistent?")
print("Isn't persistent order what makes a list a list?")
最初のアイテムを置き換えるのではなく、削除して明示的に新しいアイテムをインデックスゼロに挿入してみましたか? –
はい。同じ問題。マークされた答えは理由を説明します。クエリはデフォルトでun-orderedで発行されます。リストの順序は、リストの順序を追跡する特別な列がなければ維持できません。 –