Reputation: 95
By rowid i mean the implicit column in all sqlite tables which stores the row number.
I can use rowid in sqlite using
c.execute('SELECT rowid,* FROM table_name):
What can i do to use the rowid
value in sqlalchemy?
Upvotes: 5
Views: 2660
Reputation: 33
You can simply tell sqlalchemy not to create that field with the system
flag, and you can use it like normal in queries.
Example using more modern mapped columns:
...
class Foo(Base):
bar: Mapped[int] = mapped_column(Integer())
rowid: Mapped[int] = mapped_column(Integer(), system=True)
first_foo = session.query(Foo).filter(Foo.rowid == 1)
#From the :param hints of sqlalchemy.Column:
'''
:param system: When ``True``, indicates this is a "system" column,
that is a column which is automatically made available by the
database, and should not be included in the columns list for a
``CREATE TABLE`` statement.
For more elaborate scenarios where columns should be
conditionally rendered differently on different backends,
consider custom compilation rules for :class:`.CreateColumn`.
'''
Furthermore, if you want to access rowid on every table, then I would suggest putting the rowid attribute on the Base class instead of all of them individually:
from sqlalchemy import Integer
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
rowid: Mapped[int] = mapped_column(Integer, system=True)
Upvotes: 1
Reputation: 530
I hope this would help some one, what I found out is that you need to create the table without the rowid
column, and then you can simply map the field rowid to a column in the object.
*if you call Base.Metadata.create_all(engine)
the column rowid
will be created in the table, this will disable sqlite rowid
generation.
* didn't check what happen if the primary key is Integer, I think this will override the rowid
.
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import *
# create the table
metadata = MetaData()
user = Table('users', metadata,
Column('name', String, primary_key=True),
Column('fullname', String))
engine = create_engine('sqlite:///example.db')
metadata.create_all(engine)
# create the user object
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
name = Column(String, primary_key=True)
fullname = Column(String)
rowid = Column(Integer)
def __repr__(self):
return "User: name='%s', fullname='%s'" % (self.name, self.fullname)
# insert users
Session = sessionmaker()
Session.configure(bind=engine)
u1 = User(name='ed', fullname='Ed Jones')
u2 = User(name='fred', fullname='Fred Jones')
u3 = User(name='ted', fullname='Ted Jones', rowid=99)
session = Session()
session.add_all([u1, u2, u3])
session.commit()
# read users
users = session.query(User).all()
for user in users:
print(user, ", rowid=", user.rowid)
The output:
User: name='ed', fullname='Ed Jones' , rowid= 1
User: name='fred',fullname='Fred Jones' , rowid= 2
User: name='ted', fullname='Ted Jones' , rowid= 99
Upvotes: 1