I have, on a pgsql backend, a table and an (allegedly) random access version of it:
class Topic(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
question_id = db.Column(UUID(as_uuid=True), db.ForeignKey("question.id"))
topic = db.Column(Enum(QuestionTopicsChoices))
# Create an alias for Topic that uses BERNOULLI sampling method
Topic_rnd = db.aliased(Topic, tablesample(Topic, func.bernoulli(2.5), 10))
I'd expect, then, that these two queries return with different results:
topics_linear = Topic.query.filter_by(topic='emotion').all()
topics_random = Topic_rnd.query.filter_by(topic='emotion').all()
but they return the records in the same order. What am I doing wrong?
Related
I am not able to iterate through my query as I would like using Peewee
Those are the related Objects in Models.py
class Conversation(peewee.Model):
id = peewee.AutoField(unique=True, index=True)
creation_date = peewee.DateTimeField(default=datetime.now)
contact_id = ForeignKeyField(Contact, backref='conversation')
launch_id = ForeignKeyField(Launch, backref='conversation')
request_data = peewee.TextField(null=True)
status = peewee.TextField(null=True)
class Contact(peewee.Model):
id = peewee.AutoField(unique=True, index=True)
uuid = peewee.CharField(default=shortuuid.uuid, index=True)
whatsapp_phone = peewee.CharField(index=True, default='')
status = peewee.CharField(default='init')
conversationId = peewee.CharField(null=True)
Here's how I am trying to iterate:
for conversation in Conversation.select().where(Conversation.launch_id == str(launch_id)):
print(conversation.contact.id)
And this is the error that I a getting:
print(conversation.contact.id)
AttributeError: 'Conversation' object has no attribute 'contact'
I've tried to change the way I do my query:
query = Conversation.select(Contact).join(Contact).where(Conversation.launch_id == str(launch_id))
But I get the exact same error if I iterate in the same way.
The issue is you are, for some reason, trying to access .contact when you've named your foreign-key .contact_id. The peewee docs are clear about foreign key naming, but you want this:
class Conversation(peewee.Model):
id = peewee.AutoField(unique=True, index=True)
creation_date = peewee.DateTimeField(default=datetime.now)
# Data will be stored in a column named "contact_id":
contact = ForeignKeyField(Contact, backref='conversations')
# Data will be stored in a column named "launch_id":
launch = ForeignKeyField(Launch, backref='conversations')
request_data = peewee.TextField(null=True)
status = peewee.TextField(null=True)
This allows:
query = (Conversation
.select()
.where(Conversation.launch == str(launch_id)))
for conversation in query:
# Access the underlying foreign-key value.
print(conversation.contact_id)
Or, if you intend to access other fields on the Contact:
query = (Conversation
.select(Conversation, Contact)
.join(Contact)
.where(Conversation.launch == str(launch_id)))
for conversation in query:
# We now have a "full" Contact instance we can access efficiently:
print(conversation.contact.id)
Please read the docs:
http://docs.peewee-orm.com/en/latest/peewee/quickstart.html#lists-of-records
http://docs.peewee-orm.com/en/latest/peewee/relationships.html
http://docs.peewee-orm.com/en/latest/peewee/models.html#foreignkeyfield
Following this example I am trying to insert or update values based on a constraint. I was wondering how to set the table defaults if a value is null as you could do with pure sql string.
So far I have tried this:
....
_listing_insert_stmt = psql.insert(db.List2).values(data)
dict_keys = dict(
ChainMap(
*list(
map(
lambda x: {x[0]: getattr(_listing_insert_stmt.excluded, x[0])},
_listing_insert_stmt.excluded._collection,
),
)
)
)
listing_insert_stmt = _listing_insert_stmt.on_conflict_do_update(
constraint="ix_listings_foreign_id", set_={**dict_keys,"datetime_created":_listing_insert_stmt.excluded.datetime_created.default, "last_edited":datetime.utcnow().astimezone(pytz.UTC)}
).returning(db.List2)
listing_execution_stmt = (
select(db.List2)
.from_statement(listing_insert_stmt)
.execution_options(populate_existing=True)
)
for listing in s.execute(listing_execution_stmt).scalars():
print("inserted or updated: %s" % listing)
the table columns returned in excludes appears to not have a default set, even though it is set on my original db model
class BaseMixin(object):
id = sa.Column(psql.UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
datetime_created = sa.Column(psql.TIMESTAMP(True), server_default=sa.func.now())
last_edited = sa.Column(
psql.TIMESTAMP(True), server_default=sa.func.now(), onupdate=sa.func.now()
)
I'm wondering if the issue is happening because I am declaring the above fields as a mixin that my listings table inherits from?
class List2(Base, BaseMixin):
__tablename__ = "listings"
__table_args__ = (sa.UniqueConstraint("foreign_id"),)
I would expect it to work as this does:
INSERT INTO t (foo,bar) VALUES (1,2)
ON CONFLICT (foo) DO UPDATE
SET bar = DEFAULT;
Want to join three tables and get data. Where model_c and model_b have a foreign key to model_a. But all model does not have a foreign key
class Model_A(models.Model):
name = models.CharField()
class Model_B(models.Model):
model_a = models.ForeignKey(Model_A)
name = models.CharField()
class Model_C(models.Model):
model_a = models.ForeignKey(Model_A)
name = models.CharField()
Want query as below.
SELECT * FROM model_c JOIN model_a
ON model_a.id = model_c.model_a
JOIN model_b ON model_a
ON model_a.id = model_b.model_a;
Tried to create a query using select_related But did not work.
query = Model_C.objects.select_related('model_a', 'model_a__model_b_set')
Error
FieldError
Invalid field name(s) given in select_related: 'model_b_set'. Choices are: x, y
Tried to create a query using prefetch_related But did not work.
query = Model_C.objects.select_related('model_a', 'model_a__model_b_set')
sql = Model_C.objects.select_related().prefetch_related('model_b').query
but above query does not join.
I am trying to create Sqlite3 statement in Python 3 to collect data from two tables called FreightCargo & Train where a train ID is the input value. I want to use Pandas since its easy to read the tables.
I have created the code below which is working perfectly fine, but its static and looks for only one given line in the statement.
import pandas as pd
SQL = '''SELECT F.Cargo_ID, F.Name, F.Weight, T.Train_ID, T.Assembly_date
FROM FreightCargo F LEFT JOIN [Train] T
ON F.Cargo_ID = T.Cargo_ID
WHERE Train_ID = 2;'''
cursor = conn.cursor()
cursor.execute( SQL )
names = [x[0] for x in cursor.description]
rows = cursor.fetchall()
Temp = pd.DataFrame( rows, columns=names)
Temp'''
I want to be able to create a variable with an input. The outcome of this action will then be determined with what has been given from the user. For example the user is asked for a train_id which is a primary key in a table and the relations with the train will be listed.
I expanded the code, but I am getting an error: ValueError: operation parameter must be str
Train_ID = input('Train ID')
SQL = '''SELECT F.Cargo_ID, F.Name, F.Weight, T.Train_ID, T.Assembly_date
FROM FreightCargo F LEFT JOIN [Train] T
ON F.Cargo_ID = T.Cargo_ID
WHERE Train_ID = ?;''', (Train_ID)
cursor = conn.cursor()
cursor.execute( SQL )
names = [x[0] for x in cursor.description]
rows = cursor.fetchall()
Temp = pd.DataFrame( rows, columns=names)
Temp
The problem lays in your definition of the SQL variable.
You are creating a tuple/collection of two elements. If you print type(SQL) you will see something like this: ('''SELECT...?;''', ('your_user's_input')).
When you pass this to cursor.execute(sql[, parameters]), it is expecting a string as the first argument, with the "optional" parameters. Your parameters are not really optional, since they are defined by your SQL-query's [Train]. Parameters must be a collection, for example a tuple.
You can unwrap your SQL statement with cursor.execute(*SQL), which will pass each element of your SQL list as a different argument, or you can move the parameters to the execute function.
Train_ID = input('Train ID')
SQL = '''SELECT F.Cargo_ID, F.Name, F.Weight, T.Train_ID, T.Assembly_date
FROM FreightCargo F LEFT JOIN [Train] T
ON F.Cargo_ID = T.Cargo_ID
WHERE Train_ID = ?;'''
cursor = conn.cursor()
cursor.execute( SQL, (Train_ID,) )
names = [x[0] for x in cursor.description]
rows = cursor.fetchall()
Temp = pd.DataFrame( rows, columns=names)
Temp
Trying to join the tables below using this command:
Subscription.query.filter( return Subscription.query.filter(Subscription.watch_id == id).join(User).filter_by(watch_id=id)
I get this error:
sqlalchemy.exc.InvalidRequestError: Could not find a FROM clause to join from. Tried joining to <class 'app.user.model.User'>, but got: Can't find any foreign key relationships between 'wm_subscription' and 'user'.
Essentially my end goal is to get a query that gets a List of Users that share a watch_id. Not sure if the models or the query is correct. Anybody know what's wrong?
Database = declarative_base(cls=DbBase)
class Subscription(Database):
__tablename__ = 'wm_subscription'
subscription_id = UniqueIdPk()
watch_id = UniqueIdRefNotNull(index=True)
user_id = UniqueIdRefNotNull(ForeignKey('User.user_id'), index=True)
subscription_watch = relationship('Watch',
primaryjoin='Subscription.watch_id == Watch.watch_id',
foreign_keys='Watch.watch_id',
uselist=True)
subscription_user = relationship('User',
primaryjoin='Subscription.watch_id == User.user_id',
foreign_keys='User.user_id',
uselist=True,
backref='user')
class User(Database, UserMixin):
__tablename__ = 'user'
user_id = UniqueIdPk()
# Google sub ID - unique to user https://developers.google.com/identity/protocols/OpenIDConnect
google_id = Column(String(length=50))
# override email mixin for unique index
email = Email(unique=True)
first_name = Name()
last_name = Name()
def get_id(self):
return self.user_id
This is the correct query:
Subscription.query.filter(Subscription.watch_id == id).join(User)