I have the model below. I setup the unique constraint on the customer and the IP's in the table. I dont want to be able to add a new customer with the same name and/or ip's. If I attempt to do that, I expect SQLAlchemy to error out. Right now it is not, it is just allowing me to add multiple entries with the same IP and Customer name. My DB backend is SQLite
class SubInterfaces(db.Model):
__tablename__ = 'subinterfaces'
__table_args__ = (
db.UniqueConstraint('hub_wan1_public_ip', 'ip_transit', 'customer', 'neighbor_ip', name='unique_sub_interfaces'),
)
id = db.Column(db.Integer, primary_key=True)
carrier_vlan = db.Column(db.Integer)
cust_vlan_ipsec = db.Column(db.Integer)
cust_vlan_wan = db.Column(db.Integer)
hub_wan1_public_ip = db.Column(db.String)
ip_transit = db.Column(db.String)
neighbor_ip = db.Column(db.String)
user_account = db.Column(db.String)
customer = db.Column(db.String)
created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow())
status = db.Column(db.Integer)
location = db.Column(db.String)
is_primary = db.Column(db.Boolean)
#### Add customer piece ####
dict_to_add = {
"customer": request.json['customer'],
"hub_wan1_public_ip": request.json['HUB1_WAN1_PUBLIC_IP'],
"ip_transit": request.json['PRIMARY_TRANSIT'],
"location": request.json['LOCATION']
}
add_user = SubInterfaces(**dict_to_add)
db.session.add(add_user)
db.session.commit()
Not sure why the constrains are not working, but as a workaround I am doing a count on the DB and if more than 1, error out.
#first check if a customer exists, if it does error out
active_customer = response['customer']
count_customer = db.session.query(SubInterfaces).filter_by(customer=active_customer).count()
if (count_customer >= 1):
raise BadRequest(f"Customer {active_customer} already exists", 400, {'ext': 1})
Related
Wrapping my head around a way to get a list of Jobs associated to a User. My DB Model goes a little something like this.
class Job(db.Model):
id = db.Column(db.Integer, primary_key=True)
# Relationship Rows
actions = db.relationship('JobAction', backref='job')
class JobAction(db.Model):
id = db.Column(db.Integer, primary_key=True)
# Linked Rows
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
# Relationship Rows
user = db.relationship('User', foreign_keys=[user_id], backref='jobactions')
I need to get a list of Jobs that are associated to a User. I can use either the User already matching a logged in users details. Or the user.id.
I was looking at something like the below, but no dice. I can see it's overly optimistic a query, but can't see what's up. Potentially a missing Join.
# Get User first.
user = User.query.filter_by(id=1).first()
# Get their Jobs
jobs = Job.query.filter_by(actions.user=user).all()
Any ideas would be greatly appreciated.
Cheers,
I'm guessing you are missing a foreign key. If your database model looked like this:
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
jobactions = db.relationship("JobAction", back_populates="user")
class Job(db.Model):
__tablename__ = 'jobs'
id = db.Column(db.Integer, primary_key=True)
jobactions = db.relationship('JobAction', backref='job')
class JobAction(db.Model):
__tablename__ = 'jobactions'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
job_id = db.Column(db.Integer, db.ForeignKey('jobs.id'))
user = db.relationship(User, back_populates="jobactions")
job = db.relationship(Job, back_populates="jobactions")
Then you could use:
jobs = [ jobaction.job for jobaction in user.jobactions ]
When updating two other column values, the created column, which remains untouched on my code, updates to the current time by itself.
This is the Model
class Query(db.Model):
__tablename__ = "query"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(2000))
created = db.Column(db.DateTime)
modified = db.Column(db.DateTime)
launched = db.Column(db.Integer)
exception = db.Column(db.String(500), nullable=True)
enable = db.Column(db.Boolean)
expired = db.Column(db.Boolean)
app_id = db.Column(db.String(20))
app_secret = db.Column(db.String(40))
page_id = db.Column(db.String(20))
token = db.Column(db.String(300))
updating code
query.launched = query.launched + 1
query.modified = until
db.session.commit()
What I expected is the modified column to be updated to the 'until' time, which already happens, but the created column to stay untouched.
I got the error. It was in my sql syntax. I still didn't figure out why did it happen, but it was resolved by changing this:
-created TIMESTAMP NOT NULL
+created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
In the following code snippet, In the events table event_id is created first and then i need to insert multiple records into even_logins table based on the event_id.
class Events(db.Model):
__tablename__ = 'events'
event_name= db.column(db.String(100))
event_id = db.Column(db.String(10),primary_key=True)
scheduled_date = db.Column(db.DateTime, nullable = False)
event_logins_event_id = db.Column(db.String(10), db.ForeignKey('event_logins.event_id'))
event_registrations_event_id = db.Column(db.String(10), db.ForeignKey('event_registrations.event_id'))
class Event_logins(db.Model):
__tablename__ = 'event_logins'
event_id= db.column(db.String(10),db.ForeignKey('events.event_id'))
username = db.Column(db.String(20),primary_key=True)
password = db.Column(db.String(300))
class Event_registrations(db.Model):
__tablename__ = 'event_registrations'
event_id= db.column(db.String(10), db.ForeignKey('events.event_id'))
registration_id = db.Column(db.String(50),primary_key=True)
cust_name = db.Column(db.String(100))
cust_contactno = db.Column(db.String(50))
cust_email = db.Column(db.String(50))
cust_imageid = db.Column(db.String(200))
Finally with the below query am trying insert a record into event_logins table
event_logins = Event_logins(event_id='jk12',username='testuser', password='aaaa')
db.session.add(event_logins)
db.session.commit()
In the table it is stored as NULL the value is not being stored pls suggest
Thanks
vijay
I created a Table a Bmarks which has two foreign keys which have relation with same table Url_hash
class Hashed(Base):
__tablename__ = "url_hash"
hash_id = Column(Unicode(22), primary_key=True)
url = Column(UnicodeText)
clicks = Column(Integer, default=0)
def __init__(self, url):
cleaned_url = str(unidecode(url))
self.hash_id = unicode(generate_hash(cleaned_url))
self.url = url
class Bmark(Base):
__tablename__ = "bmarks"
bid = Column(Integer, autoincrement=True, primary_key=True)
hash_id = Column(Unicode(22), ForeignKey('url_hash.hash_id'))
clean_hash_id = Column(Unicode(22), ForeignKey('url_hash.hash_id'))
description = Column(UnicodeText())
extended = Column(UnicodeText())
stored = Column(DateTime, default=datetime.utcnow)
updated = Column(DateTime, onupdate=datetime.utcnow)
clicks = Column(Integer, default=0)
inserted_by = Column(Unicode(255))
username = Column(Unicode(255), ForeignKey('users.username'),
nullable=False,)
tag_str = Column(UnicodeText())
hashed = relation(Hashed,
foreign_keys="Bmark.hash_id",
backref="bmark",
uselist=False
)
clean_hashed = relation(Hashed,
foreign_keys="Bmark.clean_hash_id",
backref="bmark",
uselist=False
)
I am trying to store url after cleaning it a little bit like removing headers,utm parameters etc for indexing purposes
Error is occurring while creating the database
sqlalchemy.exc.ArgumentError: Error creating backref 'bmark' on relationship 'Bmark.clean_hashed': property of that name exists on mapper 'Mapper|Hashed|url_hash'
Actually the error message is very informative.
Just rename one of your backref="bmark" to something else like backref="my_clean_bmark".
I am writing a simple app that helps people call voters. I don't want my volunteers to bug any voter more than once. How can I get a list of voters who have not been called yet? I'm using flask with flask-sqlalchemy.
Voter model:
class Voter(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
phone = db.Column(db.String(20))
vanid = db.Column(db.String(20))
address = db.Column(db.String(255))
city = db.Column(db.String(255))
zip_code = db.Column(db.String(20))
lat = db.Column(db.Float)
lng = db.Column(db.Float)
...
Calls Model:
class Call(db.Model):
id = db.Column(db.Integer, primary_key=True)
voter_id = db.Column(db.Integer, db.ForeignKey('voter.id'))
voter = db.relationship('Voter', backref=db.backref('calls', lazy='dynamic'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
user = db.relationship('User', backref=db.backref('calls', lazy='dynamic'))
time = db.Column(db.DateTime)
status_code = db.Column(db.String(20))
...
call.status_code will contain values such as completed,busy,wrong_number, etc.
I want to get a list of all voters who are eligible to be called so that I can pick one to serve to the volunteer. (ie. call.status_code != completed etc. OR has no related call records)
If were to do this in raw SQL I would likely do:
Select [whatever]
FROM Voter v
LEFT JOIN Call c on c.voter_id = v.id
WHERE c.status_code IS NULL OR c.status_code = 'busy'
I can't figure it out in sqlalchemy. Any insights?
You can probably use something like :
required_voters = db.session.query(Voter).outerjoin(Call).filter((Call.voter_id == None) | (Call.status_code != 'completed'))
EDIT
Proposed query :
vwcc = db.session.query(distinct(Call.voter_id)).filter(Call.status_code == 'completed').subquery()
this will select all unique voters with completed calls
now for the main part
required_voters = db.session.query(Voter).outerjoin(Call).outerjoin(vwcc,vwcc.voter_id == Voter.id) ).filter((vwcc.voter_id == None) & ((Call.voter_id == None) | (Call.status_code != 'completed')))
This I believe will select all Voters who :
- don't have a call with completed status
and
- didn't have a call or their call didn't have completed status
Remember that I write it from mind so the syntax may be somewhat off