python - example - Sqlalchemy: crea dinámicamente una tabla desde un elemento de Scrapy
sqlalchemy select example (3)
En realidad, hay un paquete que puede ayudarte con esto.
Check out: conjunto de datos: bases de datos para personas perezosas
Aquí hay un extracto de la página:
Caracteristicas
Esquema automático:
Si se escribe una tabla o columna que no existe en la base de datos, se creará automáticamente.
Upserts:
Los registros se crean o actualizan, dependiendo de si se puede encontrar una versión existente. Consultar ayudantes para consultas simples como todas las filas en una tabla o todos los valores distintos en un conjunto de columnas.
Compatibilidad:
Al estar construido sobre SQLAlchemy, el conjunto de datos funciona con todas las bases de datos importantes, como SQLite, PostgreSQL y MySQL.
Exportaciones con guiones:
Los datos se pueden exportar en función de una configuración con guiones, por lo que el proceso es fácil y replicable.
Estoy trabajando con sqlalchemy 1.1 y scrapy. Actualmente estoy usando una canalización para almacenar datos extraídos en una tabla sqllite a través de sqlalchemy. Me gustaría crear dinámicamente una tabla para acomodar el elemento que se está raspando.
Mi elemento de tubería estática se ve así:
class SQLlitePipeline(object):
def __init__(self):
db_path = "sqlite:///"+settings.SETTINGS_PATH+"//data.db"
_engine = create_engine(db_path)
_connection = _engine.connect()
_metadata = MetaData()
_stack_items = Table(table_name, _metadata,
Column("id", Integer, primary_key=True),
Column("value", Text))
Column("value2", Text))
_metadata.create_all(_engine)
self.connection = _connection
self.stack_items = _stack_items
def process_item(self, item, spider):
try:
ins_query = self.stack_items.insert().values(
value=item[''value''],
value2=item[''value2''],)
self.connection.execute(ins_query)
except IntegrityError:
print(''THIS IS A DUP'')
return item
items.py:
class Filtered_Item(scrapy.Item):
value= scrapy.Field()
value2= scrapy.Field()
¿Cómo puedo modificar la canalización anterior para crear e insertar dinámicamente los valores del elemento filtrado en lugar de tener estos códigos rígidos como lo están ahora?
Esta no es una respuesta directa a la pregunta, sino una forma alternativa de abordar el problema.
¿Cómo puedo modificar la canalización anterior para crear e insertar dinámicamente los valores del elemento filtrado en lugar de tener estos códigos rígidos como lo están ahora?
Lo que escuché es que no quiere tener un esquema de tabla predefinido y qué su base de datos ajustar a los campos que está raspando. Bueno, esto suena como si necesitaras una base de datos sin esquemas .
Piense en cambiar a MongoDB u otros almacenamientos no esquemáticos de NoSQL. La documentación de Scrapy incluso proporciona un ejemplo de una tubería de Python + MongoDB que insertaría un elemento raspado en una colección MongoDB ("tabla" en términos de SQL) como un documento JSON:
def process_item(self, item, spider):
self.db[self.collection_name].insert(dict(item))
return item
Y, lo importante es que no importa cuáles sean los campos de item
, no hay una estructura predefinida para su documento de colección.
Esto es solo una idea: no sé mucho sobre los requisitos de su proyecto y las posibles limitaciones.
Esto es lo que se me ocurrió con base en la recomendación de conjunto de datos de Alex anterior:
import dataset
class DynamicSQLlitePipeline(object):
@classmethod
def from_crawler(cls, crawler):
# Here, you get whatever value was passed through the "target" parameter
table_name = getattr(crawler.spider, "target")
return cls(table_name)
def __init__(self,table_name):
try:
db_path = "sqlite:///"+settings.SETTINGS_PATH+"//data.db"
db = dataset.connect(db_path)
self.my_table = db[table_name]
except Exception:
traceback.exec_print()
def process_item(self, item, spider):
try:
self.my_table.insert(dict(item))
except IntegrityError:
print(''THIS IS A DUP'')
return item
Espero eso ayude.