feel free to hang here, note that some of the "chat" happens on libera.chat #sqlalchemy
users
, projects
and project_jobs
. user
can have many projects
and projects
can have many project_jobs
. Right now when I query by users
via id, I am able to access the projects with user.project
but the project_jobs
that are supposed to be in the projects
list aren't getting populated. Any ideas?
how to bypass user init method? The dunder new trick does not work
import sqlalchemy
from sqlalchemy import inspect, create_engine, Column
from sqlalchemy.pool import SingletonThreadPool
from sqlalchemy.orm import declarative_base, Session
from sqlalchemy.orm import validates
from sqlalchemy import Integer, Text
Base = declarative_base()
class TableValidator(Base):
__tablename__ = "table_validator"
id = Column(Integer, primary_key=True)
test_column = Column(Text)
def __init__(self, test_column):
self.test_column = test_column
@validates("test_column")
def validate(self, key, value):
if value is None:
raise ValueError
else:
return value
s = Session(create_engine(f"sqlite://",
connect_args={'check_same_thread': False},
poolclass=SingletonThreadPool, echo=False))
empty = TableValidator.__new__(TableValidator)
s.add(empty)
s.commit()
throws:
sqlalchemy.orm.exc.UnmappedInstanceError: Class '__main__.TableValidator' is mapped, but this instance lacks instrumentation. This occurs when the instance is created before sqlalchemy.orm.mapper(__main__.TableValidator) was called.
Hi all,
It has been only a while since I've started tinkering with SQLAlchemy. I aws working on a particular requirement of mine, where I had 4 types of users with login functionality. But each type has different attributes.
The user types are : Client, Brand, Merchant, Customer. All these types were supposed to have login access to the system. I created a parent model called User and other models like Client, Brand, Merchant and Customer inherits from the User model. I implemented it using joined table inheritance as per the documentation.
============================================================
class User(UserMixin, BaseModel):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
email = Column(String, unique=True, nullable=False, index=True)
confirmed = Column(Boolean, default=False, nullable=False)
role = Column(Enum(Role))
__mapper_args__ = {
"polymorphic_on": role,
}
=============================================================
class Client(User):
__tablename__ = "clients"
id = Column(Integer, ForeignKey("users.id"), primary_key=True)
__mapper_args__ = {
"polymorphic_identity": "client",
'inherit_condition': (id == User.id)
}
client_data = (...)
.....
================================================================
class Brand(User):
__tablename__ = "brands"
id = Column(Integer, ForeignKey("users.id"), primary_key=True)
__mapper_args__ = {
"polymorphic_identity": "brand",
'inherit_condition': id == User.id
}
brand_data = (...)
.....
Then I created an User object, which is to serve as the admin user. It works fine and well.
But the problem is when I'm creating other user types. For eg: when I'm creating a Client object, a row is created in the Client table as well as the User table. I am able to login with the client user. But the problem is when I'm trying to access the Client object's attributes. And the object type returned while querying the Client is of type User.
>>> from src.models.models import User
>>> User.get_all()
[<User 63: xxxxxxx>, <User 7: xxxxxxx>, <User 67: xxxxxxxx>, <User 13: xxxxxxxx>, <User 69: xxxxxxxxx>, <User 72: xxxxxxxx>]
>>> from src.models.models import Client
>>>
>>> Client.get_all()
[<User 7: xxxxxx>, <User 67: xxxxxxx>, <User 69: xxxxxx>]
>>>
But if I'm making the query on Client object before loading the User, it returns fine.
>>> from src.models.models import Client
>>> Client.get_all()
[<Client xxxxx>, <Client xxxxxxx>, <Client xxxxxx>]
>>>
I feel like I'm missing out on something?
I am struggling with some async session/connection issues with asyncpg with 1.4.26. I have the following:
async_session: sessionmaker = sessionmaker(
bind=engine,
class_=AsyncSession,
autocommit=False,
autoflush=False,
expire_on_commit=False,
)
...
async with async_session() as db:
...
an_obj.update_list_words(db, myman)
...
async def update_list_words(
self, db: AsyncSession, manager: EnrichmentManager
):
...
for freq, word in word_list:
data.append(UserListDict(word=word, import_frequency=int(freq)))
temp_table = f"import_{self.id}".replace("-", "_") # self.id is a GUID
sql = f"""CREATE TEMP TABLE {temp_table} (word text, import_frequency int, word_id int null, freq float null)"""
await db.execute(text(sql))
await db.execute(text( f"""INSERT INTO {temp_table} (word, import_frequency) values (:word, :import_frequency) """), data,)
await db.execute(text(
f"""UPDATE {temp_table}
SET word_id = mitable.id
FROM mitable
WHERE word = mitable.source_text
and mitable.from_lang = :from_lang
and mitable.to_lang = :to_lang"""
),
{"from_lang": manager.from_lang, "to_lang": manager.to_lang},
)
...
await db.execute(text(f"DROP TABLE {temp_table}"))
await db.commit()
I am getting some strange behaviour that I just can't understand. For example, I just got a 'asyncpg.exceptions.UndefinedTableError'>: relation "import_19fd0dbb_0321_4124_a810_22a4efee7ab1" does not exist
when it gets to the UPDATE which I am struggling to understand how it's possible. Any pointers? It works sometimes, typically the first time it gets called. Then it fails with a few different errors.
with Session.begin() as session:
while has_remaining_operations():
operations = session.query(Operation) \
.filter(
Operation.id_user == user.id and
Operation.processed_at is None
) \
.order_by(Operation.created_at.asc()) \
.limit(100) \
.all()
for op in operations:
# code to execute
op.processed_at = datetime.now().isoformat()
processed_at
modification doesn't get applied when session.query
is executed
Operation.created_at
, grab the last one from each chunk and add a WHERE Operation.created_at > last_created_at_from_previous_chunk
.filter
clause. It should have looked like this: .filter(and_(
SavedOp.id_user == user.id,
SavedOp.processed_at.is_(None)
)) \
is_(None)
is the correct form
await session.execute(
sqlalchemy.update(
some_table
).where(
some_table.id.in_(ids)
).values(
[{'a':.., ...}, {'a':.., ...},...]
),
)
UPDATE construct does not support multiple parameter sets.