Używam piramidy z Sqlalchemy, Pyramid_TM i PostgreSQL, aby to przetestować.
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
class MyList(Base):
id = Column(Integer, primary_key=True)
lst = Column(JSON)
Używam PostgreSQL 9.3+ i używając typu JSON. Kiedy to robię
mylst = MyList(lst=[])
Widzę również pustą listę [] w bazie danych, a także
def view(request):
mylst = DBSession.query(MyList).get(1)
mylst.lst.append('45')
print(DBSession.is_active, DBSession.is_modified(mylst))
Widzę ['45'] w bazie danych i wydrukuj zwroty
True, True
Kontynuacja z góry [Edytuj] na następnym wniosku (powyżej jest już zaangażowany)
def view(request):
mylst = DBSession.query(MyList).get(1)
mylst.lst.append('65')
print(DBSession.is_active, DBSession.is_modified(mylst))
DB nie zostanie zaktualizowany, nadal jest ['45'] i drukować zwroty
True, False
Czy robię coś złego lub jest to błąd?
3 odpowiedzi
Domyślnie SQLalchemy trasa tylko zmiany samej wartości, która działa "zgodnie z oczekiwaniami" dla prostych wartości, takich jak INTS i Struny:
alice.name = "Alice"
alice.age = 8
Działa również, gdy przypisujesz nową wartość do kolumny "typu złożonego", takiego jak dykt lub lista:
alice.toys = ['doll', 'teddy bear']
Jednak SQLalchemy nie zauważa zmiany, jeśli zmodyfikujesz jeden z elementów na liście, lub dołącz / usuń wartość:
alice.toys[0] = 'teapot'
alice.toys.append('lego bricks')
Aby wykonać tę pracę, możesz mieć pewność, że przydzielisz nową listę za każdym razem:
toys = alice.toys[:] # makes a "clone" of the existing list
toys[0] = 'teapot'
toys.append('lego bricks')
alice.toys = toys
Lub masz czytanie Śledzenie mutacji Rozdział w Dokumentach SQLalchemy Aby zobaczyć, jak możesz podklasować listę lub dyktować, aby śledzić modyfikacje swoich elementów.
Ponadto, ponieważ wspomniałeś, że używasz Postgres - jest dedykowany ARRAY
Typ Postgres, którego można użyć zamiast JSON
, jeśli wszystko, czego potrzebujesz, to przechowywać listy. Jednakże, co powiedziano powyżej o śledzeniu mutacji dotyczy też kolumn typu ARRAY
również.
Możesz ręcznie oznaczać instancję jako zmodyfikowaną
from sqlalchemy.orm.attributes import flag_modified
def view(session):
mylst = Session.query(MyList).get(1)
mylst.lst.append('45')
flag_modified(mylst, 'lst') # flag its `lst' attribute is modified
print(Session.is_active, Session.is_modified(mylst))
# (True, True)
Spróbuj DBSession.flush()
po mylst.lst.append('45')
. Umożliwia to zaktualizowanie DB przed Pyramid_TM wykonującą zatwierdzenie.
Więcej informacji można znaleźć tutaj: http://docs.sqlalchemy.org/ PL / Najnowsze / ORM / Session.html # Flushing
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.