Подтвердить что ты не робот

Можно ли хранить объекты класса Python в SQLite?

Я хотел бы хранить объекты Python в базе данных SQLite. Возможно ли это?

Если это так, то какие ссылки или примеры для него?

4b9b3361

Ответ 1

Вы не можете сохранить сам объект в БД. Что вы делаете, так это сохранение данных из объекта и их последующее восстановление.

Хороший способ - использовать отличную библиотеку SQLAlchemy. Он позволяет сопоставить определенный класс с таблицей в базе данных. Каждый отображаемый атрибут будет сохранен и может быть использован для восстановления объекта. Запрос базы данных возвращает экземпляры вашего класса.

С его помощью вы можете использовать не только sqlite, но и большинство баз данных. В настоящее время он также поддерживает Postgres, MySQL, Oracle, MS-SQL, Firebird, MaxDB, MS Access, Sybase, Informix и IBM DB2. И вы можете выбрать своего пользователя, какой он хочет использовать, потому что вы можете в основном переключаться между этими базами данных без изменения кода вообще.

Есть также много интересных функций - таких как автоматическая JOIN s, полиморфизация...

Быстрый, простой пример, который вы можете запустить:

from sqlalchemy import Column, Integer, Unicode, UnicodeText, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

from random import choice
from string import letters

engine = create_engine('sqlite:////tmp/teste.db', echo=True)
Base = declarative_base(bind=engine)

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(Unicode(40))
    address = Column(UnicodeText, nullable=True)
    password = Column(String(20))

    def __init__(self, name, address=None, password=None):
        self.name = name
        self.address = address
        if password is None:
            password = ''.join(choice(letters) for n in xrange(10))
        self.password = password

Base.metadata.create_all()

Session = sessionmaker(bind=engine)
s = Session()

Тогда я могу использовать его следующим образом:

# create instances of my user object
u = User('nosklo')
u.address = '66 Some Street #500'

u2 = User('lakshmipathi')
u2.password = 'ihtapimhskal'

# testing
s.add_all([u, u2])
s.commit()

Это будет работать с операторами INSERT в базе данных.

# When you query the data back it returns instances of your class:

for user in s.query(User):
    print type(user), user.name, user.password

Этот запрос будет работать SELECT users.id AS users_id, users.name AS users_name, users.address AS users_address, users.password AS users_password.

Печатным результатом будет:

<class '__main__.User'> nosklo aBPDXlTPJs
<class '__main__.User'> lakshmipathi ihtapimhskal

Итак, вы эффективно сохраняете свой объект в базе данных, наилучшим образом.

Ответ 2

Да, возможно, но есть разные подходы, и какой из них подходит, будет зависеть от ваших требований.

  • Травление

    Вы можете использовать модуль pickle для сериализации объектов, а затем сохранить эти объекты в блоке в sqlite3 (или текстовом поле, если дамп, например, кодируется base64). Помните о некоторых возможных проблемах: questions/198692/can-i-pickle-a-python-dictionary-into-a-sqlite3-text-field

  • Объектно-реляционное-Картирование

    Вы можете использовать реляционное сопоставление объектов. Это фактически создает "базу данных виртуальных объектов", которая может использоваться из языка программирования (Wikipedia). Для python для этого есть хороший инструментарий: sqlalchemy.

Ответ 3

Вы можете использовать pickle.dumps, его возвращаемые выбираемые объекты как строки, вам не нужно будет записывать их во временные файлы.

Вернуть маринованное представление объект как строка , вместо записывая его в файл.

import pickle

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)

Ответ 4

Вы можете использовать pickle для сериализации объекта. Сериализованный объект может быть вставлен в базу данных sqlite как поле bytearray.

f=open('object.dump', 'rw')
pickle.dump(obj, f)

Теперь прочитайте object.dump из файла и запишите его в базу данных sqlite. Возможно, вы захотите записать его как двоичный тип данных; читайте о хранении двоичных данных и blob в SQLite здесь. Обратите внимание, что согласно этот источник, SQLite ограничивает размер такого поля данных до 1 Мб.

Я думаю, что лучшим вариантом будет сериализация вашего объекта в файл и сохранение имени файла, а не содержимого, в базе данных.

Ответ 5

Другим выбором вместо травления является использование ORM. Это позволяет сопоставлять строки в базе данных с объектом. См. http://wiki.python.org/moin/HigherLevelDatabaseProgramming для начальной точки. Я бы рекомендовал SQLAlchemy или SQLObject.

Ответ 6

Один из вариантов заключается в использовании сопоставления O/R, например SQLObject.. Он будет выполнять большую часть сантехники, чтобы сохранить объект Python базы данных и поддерживает SQLite. Как уже упоминалось в другом месте, вы также можете сериализовать объект с помощью метода, такого как pickle, который выгружает представление объекта, которое он может восстановить, путем чтения и анализа.

Ответ 7

Существует относительно простой способ хранения и сравнения объектов, eaven для правильного индексации этих объектов и ограничения (с ubique) столбцов, содержащих объекты. И все это без использования ORM-движков. Маски объектов сохраняются с использованием дампа рассола (так что производительность может быть проблемой). Вот пример для хранения кортежей python, ограничения и сравнения индексирования. Этот метод можно легко применить к любому другому классу python. Все, что необходимо, объясняется в документации python sqlite3 (кто-то уже разместил ссылку). В любом случае, все они собраны в следующем примере:

import sqlite3
import pickle

def adapt_tuple(tuple):
    return pickle.dumps(tuple)    

sqlite3.register_adapter(tuple, adapt_tuple)    #cannot use pickle.dumps directly because of inadequate argument signature 
sqlite3.register_converter("tuple", pickle.loads)

def collate_tuple(string1, string2):
    return cmp(pickle.loads(string1), pickle.loads(string2))

# 1) Using declared types
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)

con.create_collation("cmptuple", collate_tuple)

cur = con.cursor()
cur.execute("create table test(p tuple unique collate cmptuple) ")
cur.execute("create index tuple_collated_index on test(p collate cmptuple)")


######################### Test ########################

cur.execute("select name, type  from sqlite_master") # where type = 'table'")
print(cur.fetchall())

p = (1,2,3)
p1 = (1,2)

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("insert into test(p) values (?)", (p1,))
cur.execute("insert into test(p) values (?)", ((10, 1),))
cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
cur.execute("insert into test(p) values (?)", (((9, 5), 33) ,))

try:
    cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
except Exception as e:
    print e

cur.execute("select p from test order by p")
print "\nwith declared types and default collate on column:"
for raw in cur:
    print raw

cur.execute("select p from test order by p collate cmptuple")
print "\nwith declared types collate:"
for raw in cur:
    print raw

con.create_function('pycmp', 2, cmp)

print "\nselect grater than using cmp function:"
cur.execute("select p from test where pycmp(p,?) >= 0", ((10, ),) )
for raw in cur:
    print raw

cur.execute("select p from test where pycmp(p,?) >= 0", ((3,)))
for raw in cur:
    print raw 

print "\nselect grater than using collate:"
cur.execute("select p from test where p > ?", ((10,),) )
for raw in cur:
    print raw  

cur.execute("explain query plan select p from test where p > ?", ((3,)))
for raw in cur:
    print raw

cur.close()
con.close()

Ответ 8

В зависимости от ваших конкретных потребностей, стоит рассмотреть Django (www.djangoproject.com) для выполнения этой задачи. Django на самом деле является веб-средой, но одна из задач, которую он выполняет, - это позволить вам определять Модели как объекты python (наследуя базовый класс, предоставляемый каркасом). Затем он автоматически создаст таблицы базы данных, необходимые для хранения этих объектов, а sqlite - среди поддерживаемых бэкэндов. Он также предоставляет удобные функции для запроса базы данных и возврата одного или нескольких совпадающих объектов. См. Например, документацию о моделях в django:

http://docs.djangoproject.com/en/1.9/topics/db/models/

Недостатком, конечно, является то, что вам нужно установить полную веб-инфраструктуру, и, насколько я помню, вы можете хранить объекты, атрибуты которых поддерживаются django. Кроме того, он предназначен для хранения многих экземпляров предопределенных объектов, а не для хранения одного экземпляра каждого из множества разных объектов. В зависимости от ваших потребностей это может быть или не быть непрактичным.