Tôi muốn lưu trữ các mảng numpy với các chú thích (như name
) thông qua SQLAlchemy trong một cơ sở dữ liệu quan hệ. Để làm như vậy,Làm thế nào để tích hợp SQLAlchemy và một Numpy.ndarray lớp con trơn tru và theo một cách nhiệt tình?
- tôi tách mảng NumPy từ dữ liệu của nó thông qua một đối tượng dữ liệu transfere (
DTONumpy
như một phần củaMyNumpy
). - đối tượng khó hiểu được thu thập với
Container
.
Điều gì sẽ là một cách tốt đẹp và pythonic để sửa đổi Container
(từ ví dụ dưới đây) theo một cách mà nó cung cấp như một danh sách trực tiếp MyNumpy
-objects thay vì DTONumpy
được cung cấp bởi SQLAlchemy?
Dưới đây là một minh họa về các vấn đề:
import numpy as np
import zlib
import sqlalchemy as sa
from sqlalchemy.orm import relationship, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.types import TypeDecorator, CHAR
DBSession = scoped_session(sessionmaker())
Base = declarative_base()
#### New SQLAlchemy-Type #####################
class NumpyType (sa.types.TypeDecorator):
impl = sa.types.LargeBinary
def process_bind_param(self, value, dialect):
return zlib.compress(value.dumps(), 9)
def process_result_value(self, value, dialect):
return np.loads(zlib.decompress(value))
##############################################
class DTONumpy(Base):
__tablename__ = 'dtos_numpy'
id = sa.Column(sa.Integer, primary_key=True)
amount = sa.Column('amount', NumpyType)
name = sa.Column('name', sa.String, default='')
container_id = sa.Column(sa.ForeignKey('containers.id'))
container_object = relationship(
"Container",
uselist=False,
backref='dto_numpy_objects'
)
def __init__(self, amount, name=None):
self.amount = np.array(amount)
self.name = name
class Container(Base):
__tablename__ = 'containers'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String, unique=True)
# HERE: how to access DTONumpy BUT as MyNumpy-Objects in a way that MyNumpy
# is smoothly integrated into SQLAlchemy
class MyNumpy(np.ndarray):
_DTO = DTONumpy
def __new__(cls, amount, name=''):
dto = cls._DTO(amount=amount, name=name)
return cls.newByDTO(dto)
@classmethod
def newByDTO(cls, dto):
obj = np.array(dto.amount).view(cls)
obj.setflags(write=False) # Immutable
obj._dto = dto
return obj
@property
def name(self):
return self._dto.name
if __name__ == '__main__':
engine = sa.create_engine('sqlite:///:memory:', echo=True)
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
session = DBSession()
mn1 = MyNumpy ([1,2,3], "good data")
mn2 = MyNumpy ([2,3,4], "bad data")
# Save MyNumpy-Objects
c1 = Container()
c1.name = "Test-Container"
c1.dto_numpy_objects += [mn1._dto, mn2._dto] # not a good ui
session.add(c1)
session.commit()
# Load MyNumpy-Objects
c2 = session.query(Container).filter_by(name="Test-Container").first()
# Ugly UI:
mn3 = MyNumpy.newByDTO(c2.dto_numpy_objects[0])
mn4 = MyNumpy.newByDTO(c2.dto_numpy_objects[1])
name3 = mn3._dto.name
name4 = mn4._dto.name
Container
bây giờ sẽ cung cấp một danh sách các MyNumpy
-objects và MyNumpy
-object một tham chiếu đến Container
-object theo (danh sách và tài liệu tham khảo sẽ phải lấy SQLAlchemy-mapping vào tài khoản):
type (c2.my_numpy_objects[0]) == MyNumpy
>>> True
c2.my_numpy_objects.append(MyNumpy ([7,2,5,6], "new data")
print c2.dto_numpy_objects[-1].name
>>> "new data"
Bạn đã xem [pytables] (http://www.pytables.org/moin)? Tôi đã thấy rằng các cơ sở dữ liệu quan hệ có thể gặp rắc rối khi làm việc với các mảng n-chiều. –
Với Francesc khả dĩ cung cấp một gói tuyệt vời trên thư viện hdf5, và tôi hoàn toàn đồng ý rằng đây là giải pháp thích hợp để làm việc với hệ thống phân cấp dữ liệu số! Nhưng vấn đề minh họa là một cấu trúc dữ liệu examplyfied compler hơn một trong đó là một phần một dự án đòi hỏi một cơ sở dữ liệu quan hệ như là một phụ trợ. –
Một cách để đi có thể là triển khai ListView chuyển đổi các loại. Để thấy điều đó [ở đây] (http://stackoverflow.com/questions/8984692/how-can-i-change-in-python-the-return-input-type-of-a-list-that-is-implemented -a) –