python - not - sqlalchemy select example
Cómo reflejar automáticamente la base de datos a sqlalchemy declarativo? (3)
Bueno, lo revisé, lo intenté en la base de datos de Northwind y parece prometedor. Aunque, tuve que agregar un campo de relación para poder seguir las relaciones de la base de datos.
Consideremos que no sé las relaciones entre las tablas en el momento de iniciar la aplicación, así que lo que necesito es una forma de generar automáticamente.
import unittest
from sqlalchemy import *
from sqlalchemy.orm import create_session
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
from sqlalchemy.orm import contains_eager, joinedload
from sqlalchemy.orm import relationship
#Create and engine and get the metadata
Base = declarative_base()
engine = create_engine(''mssql://user:pass@Northwind'', echo=True)
metadata = MetaData(bind=engine)
#Reflect each database table we need to use, using metadata
class Customer(Base):
__table__ = Table(''Customers'', metadata, autoload=True)
orders = relationship("Order", backref="customer")
class Shipper(Base):
__table__ = Table(''Shippers'', metadata, autoload=True)
orders = relationship("Order", backref="shipper")
class Employee(Base):
__table__ = Table(''Employees'', metadata, autoload=True)
# orders = relationship("Order", backref="employee")
territories = relationship(''Territory'', secondary=Table(''Employeeterritories'', metadata, autoload=True))
class Territory(Base):
__table__ = Table(''Territories'', metadata, autoload=True)
region = relationship(''Region'', backref=''territories'')
class Region(Base):
__table__ = Table(''Region'', metadata, autoload=True)
class Order(Base):
__table__ = Table(''Orders'', metadata, autoload=True)
products = relationship(''Product'', secondary=Table(''Order Details'', metadata, autoload=True))
employee = relationship(''Employee'', backref=''orders'')
class Product(Base):
__table__ = Table(''Products'', metadata, autoload=True)
supplier = relationship(''Supplier'', backref=''products'')
category = relationship(''Category'', backref=''products'')
class Supplier(Base):
__table__ = Table(''Suppliers'', metadata, autoload=True)
class Category(Base):
__table__ = Table(''Categories'', metadata, autoload=True)
class Test(unittest.TestCase):
def setUp(self):
#Create a session to use the tables
self.session = create_session(bind=engine)
def tearDown(self):
self.session.close()
def test_withJoins(self):
q = self.session.query(Customer)
q = q.join(Order)
q = q.join(Shipper)
q = q.filter(Customer.CustomerID ==''ALFKI'')
q = q.filter(Order.OrderID==''10643'')
q = q.filter(Shipper.ShipperID==''1'')
q = q.options(contains_eager(Customer.orders, Order.shipper))
res = q.all()
cus = res[0]
ord = cus.orders[0]
shi = ord.shipper
self.assertEqual(shi.Phone, ''(503) 555-9831'')
sqlautocode - tiene problemas con las relaciones de muchos a muchos
sqlsoup - no admite relaciones
elixir - es una nota autogenerada
¿Hay algo más que pueda probar?
En teoría, la reflexión en sqlalchemy debería funcionar para usted. En este caso, estoy usando una base de datos mssql con dos tablas que tienen una relación simple de varios a uno:
"Pruebas" con campos:
- carné de identidad
- nombre de la prueba
- author_id (clave externa a la tabla Usuarios, campo Users.id)
"Usuarios" con campos:
- carné de identidad
- nombre completo
Así que lo siguiente debe reflejar la base de datos:
from sqlalchemy import *
from sqlalchemy.orm import create_session
from sqlalchemy.ext.declarative import declarative_base
#Create and engine and get the metadata
Base = declarative_base()
engine = create_engine(''put your database connect string here'')
metadata = MetaData(bind=engine)
#Reflect each database table we need to use, using metadata
class Tests(Base):
__table__ = Table(''Tests'', metadata, autoload=True)
class Users(Base):
__table__ = Table(''Users'', metadata, autoload=True)
#Create a session to use the tables
session = create_session(bind=engine)
#Here I will just query some data using my foreign key relation, as you would
#normally do if you had created a declarative data mode.
#Note that not all test records have an author so I need to accomodate for Null records
testlist = session.query(Tests).all()
for test in testlist:
testauthor = session.query(Users).filter_by(id=test.author_id).first()
if not testauthor:
print "Test Name: {}, No author recorded".format(test.testname)
else:
print "Test Name: {}, Test Author: {}".format(test.testname, testauthor.fullname)
Así que esto parece funcionar con relaciones de mesa. Aunque todavía no ha dado mucho detalle a lo que está tratando de hacer exactamente.
Podría usar sqlacodegen para generar todos los modelos de la base de datos. Sin embargo, es necesario cuidar de la clave externa manualmente.